summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/TargetInfo.h4
-rw-r--r--clang/lib/Basic/Targets.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp2
-rw-r--r--clang/test/Sema/attr-mode.c11
4 files changed, 16 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index f1d83381707..69aab0ef8ce 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -413,10 +413,10 @@ public:
}
// Return the size of unwind_word for this target.
- unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
+ virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
/// \brief Return the "preferred" register width on this target.
- unsigned getRegisterWidth() const {
+ virtual unsigned getRegisterWidth() const {
// Currently we assume the register width on the target matches the pointer
// width, we can introduce a new variable for this if/when some target wants
// it.
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index d75aa3e0095..3f4c1aa12c9 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -4029,6 +4029,8 @@ public:
// for x32 we need it here explicitly
bool hasInt128Type() const override { return true; }
+ unsigned getUnwindWordWidth() const override { return 64; }
+ unsigned getRegisterWidth() const override { return 64; }
bool validateGlobalRegisterVariable(StringRef RegName,
unsigned RegSize,
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b2169962a5d..eb8a49c9745 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3332,7 +3332,7 @@ static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
// FIXME: glibc uses 'word' to define register_t; this is narrower than a
// pointer on PIC16 and other embedded platforms.
if (Str == "word")
- DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
+ DestWidth = S.Context.getTargetInfo().getRegisterWidth();
else if (Str == "byte")
DestWidth = S.Context.getTargetInfo().getCharWidth();
break;
diff --git a/clang/test/Sema/attr-mode.c b/clang/test/Sema/attr-mode.c
index 179b1819b1f..405bfb76d1a 100644
--- a/clang/test/Sema/attr-mode.c
+++ b/clang/test/Sema/attr-mode.c
@@ -4,6 +4,8 @@
// RUN: -verify %s
// RUN: %clang_cc1 -triple powerpc64-pc-linux-gnu -DTEST_64BIT_PPC64 -fsyntax-only \
// RUN: -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnux32 -DTEST_64BIT_X86 -fsyntax-only \
+// RUN: -verify %s
typedef int i16_1 __attribute((mode(HI)));
int i16_1_test[sizeof(i16_1) == 2 ? 1 : -1];
@@ -63,8 +65,17 @@ void test_int_to_ui32(unsigned int* y) { f_ui32_arg(y); }
void test_long_to_i64(long long* y) { f_i64_arg(y); }
void test_long_to_ui64(unsigned long long* y) { f_ui64_arg(y); }
#elif TEST_64BIT_X86
+#ifdef __ILP32__
+typedef unsigned int gcc_word __attribute__((mode(word)));
+int foo[sizeof(gcc_word) == 8 ? 1 : -1];
+typedef unsigned int gcc_unwind_word __attribute__((mode(unwind_word)));
+int foo[sizeof(gcc_unwind_word) == 8 ? 1 : -1];
+void test_long_to_i64(long long* y) { f_i64_arg(y); }
+void test_long_to_ui64(unsigned long long* y) { f_ui64_arg(y); }
+#else
void test_long_to_i64(long* y) { f_i64_arg(y); }
void test_long_to_ui64(unsigned long* y) { f_ui64_arg(y); }
+#endif
typedef float f128ibm __attribute__ ((mode (TF))); // expected-error{{unsupported machine mode 'TF'}}
#elif TEST_64BIT_PPC64
typedef float f128ibm __attribute__ ((mode (TF)));
OpenPOWER on IntegriCloud