diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /test/Sema | |
parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff) | |
download | src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip |
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes:
svn path=/vendor/clang/dist/; revision=326941
svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'test/Sema')
77 files changed, 3183 insertions, 122 deletions
diff --git a/test/Sema/Inputs/pragma-pack1.h b/test/Sema/Inputs/pragma-pack1.h new file mode 100644 index 000000000000..abbf8a8609f1 --- /dev/null +++ b/test/Sema/Inputs/pragma-pack1.h @@ -0,0 +1,27 @@ + +#ifndef NO_RECORD_1 +struct ReceivesPragma { }; +#endif + +#ifdef SET_FIRST_HEADER +#pragma pack (16) +#ifndef SET_SECOND_HEADER +// expected-note@-2 2 {{previous '#pragma pack' directive that modifies alignment is here}} +#else +// expected-note@-4 1 {{previous '#pragma pack' directive that modifies alignment is here}} +#endif +// expected-warning@+3 {{non-default #pragma pack value changes the alignment of struct or union members in the included file}} +#endif + +#include "pragma-pack2.h" + +#ifdef SET_SECOND_HEADER +// expected-warning@-3 {{the current #pragma pack aligment value is modified in the included file}} +#endif + +#ifdef PUSH_POP_FIRST_HEADER +// This is fine, we don't change the current value. +#pragma pack (push, 4) + +#pragma pack (pop) +#endif diff --git a/test/Sema/Inputs/pragma-pack2.h b/test/Sema/Inputs/pragma-pack2.h new file mode 100644 index 000000000000..a41621544d75 --- /dev/null +++ b/test/Sema/Inputs/pragma-pack2.h @@ -0,0 +1,8 @@ + +#ifndef NO_RECORD_2 +struct S { int x; }; +#endif + +#ifdef SET_SECOND_HEADER +#pragma pack (8) // expected-note 2 {{previous '#pragma pack' directive that modifies alignment is here}} +#endif diff --git a/test/Sema/_Float128.c b/test/Sema/_Float128.c new file mode 100644 index 000000000000..f0c3c6d555ef --- /dev/null +++ b/test/Sema/_Float128.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -triple powerpc64-linux -verify %s +// RUN: %clang_cc1 -triple i686-windows-gnu -verify %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -verify %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -verify %s + +#if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) +_Float128 f; +_Float128 tiny = __FLT128_EPSILON__; +int g(int x, _Float128 *y) { + return x + *y; +} + +// expected-no-diagnostics +#else +_Float128 f; // expected-error {{__float128 is not supported on this target}} +float tiny = __FLT128_EPSILON__; // expected-error{{use of undeclared identifier}} +int g(int x, _Float128 *y) { // expected-error {{__float128 is not supported on this target}} + return x + *y; +} + +#endif // defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) diff --git a/test/Sema/assign.c b/test/Sema/assign.c index 1fff77864420..5bdfa9a3a5df 100644 --- a/test/Sema/assign.c +++ b/test/Sema/assign.c @@ -16,3 +16,46 @@ void test3() { b[4] = 1; // expected-error {{read-only variable is not assignable}} b2[4] = 1; // expected-error {{read-only variable is not assignable}} } + +typedef struct I { + const int a; // expected-note 4{{nested data member 'a' declared const here}} \ + expected-note 6{{data member 'a' declared const here}} +} I; +typedef struct J { + struct I i; +} J; +typedef struct K { + struct J *j; +} K; + +void testI(struct I i1, struct I i2) { + i1 = i2; // expected-error {{cannot assign to variable 'i1' with const-qualified data member 'a'}} +} +void testJ1(struct J j1, struct J j2) { + j1 = j2; // expected-error {{cannot assign to variable 'j1' with nested const-qualified data member 'a'}} +} +void testJ2(struct J j, struct I i) { + j.i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}} +} +void testK1(struct K k, struct J j) { + *(k.j) = j; // expected-error {{cannot assign to lvalue with nested const-qualified data member 'a'}} +} +void testK2(struct K k, struct I i) { + k.j->i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}} +} + +void testI_(I i1, I i2) { + i1 = i2; // expected-error {{cannot assign to variable 'i1' with const-qualified data member 'a'}} +} +void testJ1_(J j1, J j2) { + j1 = j2; // expected-error {{cannot assign to variable 'j1' with nested const-qualified data member 'a'}} +} +void testJ2_(J j, I i) { + j.i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}} +} +void testK1_(K k, J j) { + *(k.j) = j; // expected-error {{cannot assign to lvalue with nested const-qualified data member 'a'}} +} +void testK2_(K k, I i) { + k.j->i = i; // expected-error {{cannot assign to non-static data member 'i' with const-qualified data member 'a'}} +} diff --git a/test/Sema/attr-alias.c b/test/Sema/attr-alias.c index 151052f89e51..93136706a7e5 100644 --- a/test/Sema/attr-alias.c +++ b/test/Sema/attr-alias.c @@ -2,7 +2,4 @@ void g() {} -// It is important that the following string be in the error message. The gcc -// testsuite looks for it to decide if a target supports aliases. - -void f() __attribute__((alias("g"))); //expected-error {{only weak aliases are supported}} +void f() __attribute__((alias("g"))); //expected-error {{aliases are not supported on darwin}} diff --git a/test/Sema/attr-availability-app-extensions.c b/test/Sema/attr-availability-app-extensions.c index 8f9dcbc763d1..c66c14ed1a15 100644 --- a/test/Sema/attr-availability-app-extensions.c +++ b/test/Sema/attr-availability-app-extensions.c @@ -21,8 +21,19 @@ __attribute__((availability(ios,unavailable))) #endif void f1(int); // expected-note {{'f1' has been explicitly marked unavailable here}} +#if __has_feature(attribute_availability_app_extension) + __attribute__((availability(macOSApplicationExtension,unavailable))) +#ifndef TVOS + __attribute__((availability(iOSApplicationExtension,unavailable))) +#else + __attribute__((availability(tvOSApplicationExtension,unavailable))) +#endif +#endif +void f2(int); // expected-note {{'f2' has been explicitly marked unavailable here}} + void test() { f0(1); // expected-error {{'f0' is unavailable: not available on}} f1(1); // expected-error {{'f1' is unavailable}} + f2(2); // expected-error {{'f2' is unavailable: not available on}} } diff --git a/test/Sema/attr-availability-ios.c b/test/Sema/attr-availability-ios.c index 6462d58beec0..3f901bb33cb5 100644 --- a/test/Sema/attr-availability-ios.c +++ b/test/Sema/attr-availability-ios.c @@ -2,13 +2,13 @@ void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}} void f1(int) __attribute__((availability(ios,introduced=2.1))); -void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}} +void f2(int) __attribute__((availability(iOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}} void f3(int) __attribute__((availability(ios,introduced=3.0))); void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}} void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}} void f6(int) __attribute__((availability(ios,deprecated=3.0))); -void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}} +void f6(int) __attribute__((availability(iOS,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}} void test() { f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}} diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c index f422811708fa..d39086985088 100644 --- a/test/Sema/attr-availability-macosx.c +++ b/test/Sema/attr-availability-macosx.c @@ -10,7 +10,7 @@ void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5) void f3(int) __attribute__((availability(macosx,introduced=10.6))); void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}} void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}} -void f6(int) __attribute__((availability(macosx,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}} +void f6(int) __attribute__((availability(macOS,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}} void test() { f0(0); @@ -47,7 +47,7 @@ enum __attribute__((availability(macosx,introduced=8.0,deprecated=9.0))) { }; // Make sure the note is on the declaration with the actual availability attributes. -struct __attribute__((availability(macosx,strict,introduced=10.9))) type_info // \ +struct __attribute__((availability(macOS,strict,introduced=10.9))) type_info // \ expected-note{{'type_info' has been explicitly marked unavailable here}} { }; diff --git a/test/Sema/attr-availability-tvos.c b/test/Sema/attr-availability-tvos.c index 642246425b37..d53d6ac8edc4 100644 --- a/test/Sema/attr-availability-tvos.c +++ b/test/Sema/attr-availability-tvos.c @@ -36,7 +36,7 @@ void f10(int); // Test tvOS specific attributes. void f0_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_tvos' has been explicitly marked deprecated here}} void f1_tvos(int) __attribute__((availability(tvos,introduced=2.1))); -void f2_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}} +void f2_tvos(int) __attribute__((availability(tvOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}} void f3_tvos(int) __attribute__((availability(tvos,introduced=3.0))); void f4_tvos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}} void f5_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); @@ -44,7 +44,7 @@ void f5_attr_reversed_tvos(int) __attribute__((availability(ios, deprecated=3.0) void f5b_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}} void f5c_tvos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}} void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0))); -void f6_tvos(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}} +void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}} void test_tvos() { f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 2.1}} diff --git a/test/Sema/attr-availability-watchos.c b/test/Sema/attr-availability-watchos.c index cb9f968bd6ab..ec7f3a7d3afd 100644 --- a/test/Sema/attr-availability-watchos.c +++ b/test/Sema/attr-availability-watchos.c @@ -25,7 +25,7 @@ void test() { // Test watchOS specific attributes. void f0_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_watchos' has been explicitly marked deprecated here}} void f1_watchos(int) __attribute__((availability(watchos,introduced=2.1))); -void f2_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}} +void f2_watchos(int) __attribute__((availability(watchOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}} void f3_watchos(int) __attribute__((availability(watchos,introduced=3.0))); void f4_watchos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(watchos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}} void f5_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); @@ -33,7 +33,7 @@ void f5_attr_reversed_watchos(int) __attribute__((availability(ios, deprecated=3 void f5b_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5b_watchos' has been explicitly marked deprecated here}} void f5c_watchos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_watchos' has been explicitly marked deprecated here}} void f6_watchos(int) __attribute__((availability(watchos,deprecated=3.0))); -void f6_watchos(int) __attribute__((availability(watchos,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}} +void f6_watchos(int) __attribute__((availability(watchOS,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}} void test_watchos() { f0_watchos(0); // expected-warning{{'f0_watchos' is deprecated: first deprecated in watchOS 2.1}} diff --git a/test/Sema/attr-capabilities.c b/test/Sema/attr-capabilities.c index 89967704865f..21cbae9e6090 100644 --- a/test/Sema/attr-capabilities.c +++ b/test/Sema/attr-capabilities.c @@ -11,8 +11,8 @@ typedef union { int a; char* b; } __attribute__((capability("mutex"))) MutexUnio // Test an invalid capability name struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}} -int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs, unions, and typedefs}} -int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, and typedefs}} +int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs, unions, classes, and typedefs}} +int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, classes, and typedefs}} int Test3 __attribute__((acquire_capability("test3"))); // expected-warning {{'acquire_capability' attribute only applies to functions}} int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}} int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}} @@ -37,9 +37,6 @@ void Func6(void) __attribute__((requires_shared_capability(BadCapability))) {} void Func7(void) __attribute__((assert_capability(GUI))) {} void Func8(void) __attribute__((assert_shared_capability(GUI))) {} -void Func9(void) __attribute__((assert_capability())) {} // expected-error {{'assert_capability' attribute takes one argument}} -void Func10(void) __attribute__((assert_shared_capability())) {} // expected-error {{'assert_shared_capability' attribute takes one argument}} - void Func11(void) __attribute__((acquire_capability(GUI))) {} void Func12(void) __attribute__((acquire_shared_capability(GUI))) {} diff --git a/test/Sema/attr-capabilities.cpp b/test/Sema/attr-capabilities.cpp new file mode 100644 index 000000000000..5bae94edaa41 --- /dev/null +++ b/test/Sema/attr-capabilities.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s + +class __attribute__((shared_capability("mutex"))) Mutex { + public: + void func1() __attribute__((assert_capability(this))); + void func2() __attribute__((assert_capability(!this))); + + const Mutex& operator!() const { return *this; } +}; + +class NotACapability { + public: + void func1() __attribute__((assert_capability(this))); // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'NotACapability *'}} + void func2() __attribute__((assert_capability(!this))); // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'bool'}} + + const NotACapability& operator!() const { return *this; } +}; diff --git a/test/Sema/attr-cleanup.c b/test/Sema/attr-cleanup.c index 26f283a1a4fa..36692898c191 100644 --- a/test/Sema/attr-cleanup.c +++ b/test/Sema/attr-cleanup.c @@ -2,16 +2,16 @@ void c1(int *a); -extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}} -int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}} -static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}} +extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} +int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} +static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} void t1() { int v1 __attribute((cleanup)); // expected-error {{'cleanup' attribute takes one argument}} int v2 __attribute((cleanup(1, 2))); // expected-error {{'cleanup' attribute takes one argument}} - static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}} + static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} int v4 __attribute((cleanup(h))); // expected-error {{use of undeclared identifier 'h'}} @@ -46,3 +46,5 @@ void t5() { void t6(void) { int i __attribute__((cleanup((void *)0))); // expected-error {{'cleanup' argument is not a function}} } + +void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' attribute only applies to local variables}} diff --git a/test/Sema/attr-deprecated-c2x.c b/test/Sema/attr-deprecated-c2x.c new file mode 100644 index 000000000000..2505f1294c38 --- /dev/null +++ b/test/Sema/attr-deprecated-c2x.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -fdouble-square-bracket-attributes + +int f() [[deprecated]]; // expected-note 2 {{'f' has been explicitly marked deprecated here}} +void g() [[deprecated]];// expected-note {{'g' has been explicitly marked deprecated here}} +void g(); + +extern int var [[deprecated]]; // expected-note 2 {{'var' has been explicitly marked deprecated here}} + +int a() { + int (*ptr)() = f; // expected-warning {{'f' is deprecated}} + f(); // expected-warning {{'f' is deprecated}} + + // test if attributes propagate to functions + g(); // expected-warning {{'g' is deprecated}} + + return var; // expected-warning {{'var' is deprecated}} +} + +// test if attributes propagate to variables +extern int var; +int w() { + return var; // expected-warning {{'var' is deprecated}} +} + +int old_fn() [[deprecated]];// expected-note {{'old_fn' has been explicitly marked deprecated here}} +int old_fn(); +int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}} + +int old_fn() { + return old_fn()+1; // no warning, deprecated functions can use deprecated symbols. +} + +struct foo { + int x [[deprecated]]; // expected-note 3 {{'x' has been explicitly marked deprecated here}} +}; + +void test1(struct foo *F) { + ++F->x; // expected-warning {{'x' is deprecated}} + struct foo f1 = { .x = 17 }; // expected-warning {{'x' is deprecated}} + struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}} +} + +typedef struct foo foo_dep [[deprecated]]; // expected-note {{'foo_dep' has been explicitly marked deprecated here}} +foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}} + +struct [[deprecated, // expected-note {{'bar_dep' has been explicitly marked deprecated here}} + invalid_attribute]] bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}} + +struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}} + +[[deprecated("this is the message")]] int i; // expected-note {{'i' has been explicitly marked deprecated here}} +void test4(void) { + i = 12; // expected-warning {{'i' is deprecated: this is the message}} +} diff --git a/test/Sema/attr-disable-tail-calls.c b/test/Sema/attr-disable-tail-calls.c index 4574d5e0b66b..e8f5bcc73ee8 100644 --- a/test/Sema/attr-disable-tail-calls.c +++ b/test/Sema/attr-disable-tail-calls.c @@ -8,6 +8,6 @@ void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error { __asm__(""); } -int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and methods}} +int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and Objective-C methods}} int foo3(int a) __attribute__((disable_tail_calls("abc"))); // expected-error {{'disable_tail_calls' attribute takes no arguments}} diff --git a/test/Sema/attr-long-call.c b/test/Sema/attr-long-call.c new file mode 100644 index 000000000000..cd3de1bf9e41 --- /dev/null +++ b/test/Sema/attr-long-call.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -fsyntax-only -verify %s + +__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}} +__attribute__((short_call(0))) void foo9(); // expected-error {{'short_call' attribute takes no arguments}} +__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}} +__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}} + +__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((short_call)) int d; // expected-warning {{attribute only applies to functions}} +__attribute((far)) int a; // expected-warning {{attribute only applies to functions}} +__attribute((near)) int a; // expected-warning {{attribute only applies to functions}} + +__attribute((long_call)) void foo4(); +__attribute((short_call)) void foo10(); +__attribute((far)) void foo5(); +__attribute((near)) void foo6(); + +__attribute((long_call, far)) void foo7(); +__attribute((short_call, near)) void foo11(); + +__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} + +__attribute((short_call, long_call)) void foo12(); // expected-error {{'short_call' and 'long_call' attributes are not compatible}} \ + // expected-note {{conflicting attribute is here}} diff --git a/test/Sema/attr-minsize.c b/test/Sema/attr-minsize.c index 7b1c6ae66f1b..d2374b6113be 100644 --- a/test/Sema/attr-minsize.c +++ b/test/Sema/attr-minsize.c @@ -2,4 +2,4 @@ int foo() __attribute__((__minsize__)); -int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and methods}} +int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and Objective-C methods}} diff --git a/test/Sema/attr-mode.c b/test/Sema/attr-mode.c index e160d8d4846d..c0e0426e0098 100644 --- a/test/Sema/attr-mode.c +++ b/test/Sema/attr-mode.c @@ -26,8 +26,8 @@ typedef unsigned unwind_word __attribute((mode(unwind_word))); int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}} -__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}} -enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}} +__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}} +enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to}} typedef _Complex double c32 __attribute((mode(SC))); int c32_test[sizeof(c32) == 8 ? 1 : -1]; diff --git a/test/Sema/attr-nodebug.c b/test/Sema/attr-nodebug.c index e7ca58d3ba15..355778411d3e 100644 --- a/test/Sema/attr-nodebug.c +++ b/test/Sema/attr-nodebug.c @@ -2,7 +2,7 @@ int a __attribute__((nodebug)); -void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to variables and functions}} +void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to functions, function pointers, Objective-C methods, and variables}} int b __attribute__((nodebug)); } diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c index c64b10d80ff6..bc4247411130 100644 --- a/test/Sema/attr-section.c +++ b/test/Sema/attr-section.c @@ -10,7 +10,7 @@ int y __attribute__((section( // PR6007 void test() { - __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}} + __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, global variables, Objective-C methods, and Objective-C properties}} __attribute__((section("NEAR,x"))) static int n2; // ok. } @@ -18,4 +18,17 @@ void test() { void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}} void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}} -enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}} +enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to}} + +extern int a; // expected-note {{previous declaration is here}} +int *b = &a; +extern int a __attribute__((section("foo,zed"))); // expected-warning {{section attribute is specified on redeclared variable}} + +// Not a warning. +int c; +int c __attribute__((section("foo,zed"))); + +// Also OK. +struct r_debug {}; +extern struct r_debug _r_debug; +struct r_debug _r_debug __attribute__((nocommon, section(".r_debug,bar"))); diff --git a/test/Sema/attr-target.c b/test/Sema/attr-target.c index 6c6b461904d1..058bfc421a19 100644 --- a/test/Sema/attr-target.c +++ b/test/Sema/attr-target.c @@ -2,7 +2,13 @@ int __attribute__((target("avx,sse4.2,arch=ivybridge"))) foo() { return 4; } int __attribute__((target())) bar() { return 4; } //expected-error {{'target' attribute takes one argument}} -int __attribute__((target("tune=sandybridge"))) baz() { return 4; } //expected-warning {{Ignoring unsupported 'tune=' in the target attribute string}} -int __attribute__((target("fpmath=387"))) walrus() { return 4; } //expected-warning {{Ignoring unsupported 'fpmath=' in the target attribute string}} +int __attribute__((target("tune=sandybridge"))) baz() { return 4; } //expected-warning {{ignoring unsupported 'tune=' in the target attribute string}} +int __attribute__((target("fpmath=387"))) walrus() { return 4; } //expected-warning {{ignoring unsupported 'fpmath=' in the target attribute string}} +int __attribute__((target("avx,sse4.2,arch=hiss"))) meow() { return 4; }//expected-warning {{ignoring unsupported architecture 'hiss' in the target attribute string}} +int __attribute__((target("woof"))) bark() { return 4; }//expected-warning {{ignoring unsupported 'woof' in the target attribute string}} +int __attribute__((target("arch="))) turtle() { return 4; } // no warning, same as saying 'nothing'. +int __attribute__((target("arch=hiss,arch=woof"))) pine_tree() { return 4; } //expected-warning {{ignoring unsupported architecture 'hiss' in the target attribute string}} +int __attribute__((target("arch=ivybridge,arch=haswell"))) oak_tree() { return 4; } //expected-warning {{ignoring duplicate 'arch=' in the target attribute string}} + diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c index df74554487e2..e3610caba584 100644 --- a/test/Sema/attr-weak.c +++ b/test/Sema/attr-weak.c @@ -5,10 +5,10 @@ extern int g1 __attribute__((weak_import)); int g2 __attribute__((weak)); int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}} int __attribute__((weak_import)) g4(void); -void __attribute__((weak_import)) g5(void) { +void __attribute__((weak_import)) g5(void) { } -struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables and functions}} +struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables, functions, and classes}} struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}} static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} diff --git a/test/Sema/builtin-assume-aligned.c b/test/Sema/builtin-assume-aligned.c index 33c1b74488e1..057a500b321a 100644 --- a/test/Sema/builtin-assume-aligned.c +++ b/test/Sema/builtin-assume-aligned.c @@ -47,7 +47,7 @@ void test_void_assume_aligned(void) __attribute__((assume_aligned(32))); // expe int test_int_assume_aligned(void) __attribute__((assume_aligned(16))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}} void *test_ptr_assume_aligned(void) __attribute__((assume_aligned(64))); // no-warning -int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to functions and methods}} +int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to Objective-C methods and functions}} void *test_no_fn_proto() __attribute__((assume_aligned(32))); // no-warning void *test_with_fn_proto(void) __attribute__((assume_aligned(128))); // no-warning diff --git a/test/Sema/builtin-cpu-supports.c b/test/Sema/builtin-cpu-supports.c index c537b4140b27..026b5b7e38e9 100644 --- a/test/Sema/builtin-cpu-supports.c +++ b/test/Sema/builtin-cpu-supports.c @@ -12,9 +12,15 @@ int main() { if (__builtin_cpu_supports(str)) // expected-error {{expression is not a string literal}} a(str); + + if (__builtin_cpu_is("int")) // expected-error {{invalid cpu name for builtin}} + a("intel"); #else if (__builtin_cpu_supports("vsx")) // expected-error {{use of unknown builtin}} a("vsx"); + + if (__builtin_cpu_is("pwr9")) // expected-error {{use of unknown builtin}} + a("pwr9"); #endif return 0; diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c index 668b8284ffeb..373bbae31e7f 100644 --- a/test/Sema/builtins-arm.c +++ b/test/Sema/builtins-arm.c @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -triple armv7 -target-abi apcs-gnu \ // RUN: -fsyntax-only -verify %s +#include <arm_acle.h> + void f(void *a, void *b) { __clear_cache(); // expected-error {{too few arguments to function call, expected 2, have 0}} // expected-note {{'__clear_cache' is a builtin with type 'void (void *, void *)}} __clear_cache(a); // expected-error {{too few arguments to function call, expected 2, have 1}} @@ -136,3 +138,185 @@ void test6(int a, int b, int c) { __builtin_arm_mrrc2(15, a, 0); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}} __builtin_arm_mrrc2(15, 0, a); // expected-error {{argument to '__builtin_arm_mrrc2' must be a constant integer}} } + +void test_9_3_multiplications(int a, int b) { + int r; + r = __builtin_arm_smulbb(a, b); + r = __builtin_arm_smulbb(1, -9); + + r = __builtin_arm_smulbt(a, b); + r = __builtin_arm_smulbt(0, b); + + r = __builtin_arm_smultb(a, b); + r = __builtin_arm_smultb(5, b); + + r = __builtin_arm_smultt(a, b); + r = __builtin_arm_smultt(a, -1); + + r = __builtin_arm_smulwb(a, b); + r = __builtin_arm_smulwb(1, 2); + + r = __builtin_arm_smulwt(a, b); + r = __builtin_arm_smulwt(-1, -2); + r = __builtin_arm_smulwt(-1.0f, -2); +} + +void test_9_4_1_width_specified_saturation(int a, int b) { + unsigned u; + int s; + + s = __builtin_arm_ssat(8, 2); + s = __builtin_arm_ssat(a, 1); + s = __builtin_arm_ssat(a, 32); + s = __builtin_arm_ssat(a, 0); // expected-error {{argument should be a value from 1 to 32}} + s = __builtin_arm_ssat(a, 33); // expected-error {{argument should be a value from 1 to 32}} + s = __builtin_arm_ssat(a, b); // expected-error {{argument to '__builtin_arm_ssat' must be a constant integer}} + + u = __builtin_arm_usat(8, 2); + u = __builtin_arm_usat(a, 0); + u = __builtin_arm_usat(a, 31); + u = __builtin_arm_usat(a, 32); // expected-error {{argument should be a value from 0 to 31}} + u = __builtin_arm_usat(a, b); // expected-error {{argument to '__builtin_arm_usat' must be a constant integer}} +} + +void test_9_4_2_saturating_addition_subtraction(int a, int b) { + int s; + s = __builtin_arm_qadd(a, b); + s = __builtin_arm_qadd(-1, 0); + + s = __builtin_arm_qsub(a, b); + s = __builtin_arm_qsub(0, -1); + + s = __builtin_arm_qdbl(a); +} + +void test_9_4_3_accumulating_multiplications(int a, int b, int c) { + int s; + + s = __builtin_arm_smlabb(a, b, c); + s = __builtin_arm_smlabb(1, b, c); + s = __builtin_arm_smlabb(a, 2, c); + s = __builtin_arm_smlabb(a, b, -3); + + s = __builtin_arm_smlabt(a, b, c); + s = __builtin_arm_smlabt(1, b, c); + s = __builtin_arm_smlabt(a, 2, c); + s = __builtin_arm_smlabt(a, b, -3); + + s = __builtin_arm_smlatb(a, b, c); + s = __builtin_arm_smlatt(1, b, c); + s = __builtin_arm_smlawb(a, 2, c); + s = __builtin_arm_smlawt(a, b, -3); +} + +void test_9_5_4_parallel_16bit_saturation(int16x2_t a) { + unsigned u; + int s; + + s = __builtin_arm_ssat16(a, 1); + s = __builtin_arm_ssat16(a, 16); + s = __builtin_arm_ssat16(a, 0); // expected-error {{argument should be a value from 1 to 16}} + s = __builtin_arm_ssat16(a, 17); // expected-error {{argument should be a value from 1 to 16}} + + u = __builtin_arm_usat16(a, 0); + u = __builtin_arm_usat16(a, 15); + u = __builtin_arm_usat16(a, 16); // expected-error {{argument should be a value from 0 to 15}} +} + +void test_9_5_5_packing_and_unpacking(int16x2_t a, int8x4_t b, uint16x2_t c, uint8x4_t d) { + int16x2_t x; + uint16x2_t y; + + x = __builtin_arm_sxtab16(a, b); + x = __builtin_arm_sxtab16(1, -1); + x = __builtin_arm_sxtb16(b); + x = __builtin_arm_sxtb16(-b); + + y = __builtin_arm_uxtab16(c, d); + y = __builtin_arm_uxtab16(-1, -2); + y = __builtin_arm_uxtb16(d); + y = __builtin_arm_uxtb16(-1); +} + +uint8x4_t +test_9_5_6_parallel_selection(uint8x4_t a, uint8x4_t b) { + return __builtin_arm_sel(a, b); +} + +void test_9_5_7_parallel_8bit_addition_substraction(int8x4_t a, int8x4_t b, + uint8x4_t c, uint8x4_t d) { + int8x4_t s; + uint8x4_t u; + + s = __builtin_arm_qadd8(a, b); + s = __builtin_arm_qsub8(a, b); + s = __builtin_arm_sadd8(a, b); + s = __builtin_arm_shadd8(a, b); + s = __builtin_arm_shsub8(a, b); + s = __builtin_arm_ssub8(a, b); + + u = __builtin_arm_uadd8(c, d); + u = __builtin_arm_uhadd8(c, d); + u = __builtin_arm_uhsub8(c, d); + u = __builtin_arm_uqadd8(c, d); + u = __builtin_arm_uqsub8(c, d); + u = __builtin_arm_usub8(c, d); +} + +void test_9_5_8_absolute_differences(uint8x4_t a, uint8x4_t b, uint32_t c) { + uint32_t r; + + r = __builtin_arm_usad8(a, b); + r = __builtin_arm_usada8(a, b, c); +} + +void test_9_5_9_parallel_addition_and_subtraction(int16x2_t a, int16x2_t b, + uint16x2_t c, uint16x2_t d) { + int16x2_t x; + uint16x2_t y; + + x = __builtin_arm_qadd16(a, b); + x = __builtin_arm_qasx(a, b); + x = __builtin_arm_qsax(a, b); + x = __builtin_arm_qsub16(a, b); + x = __builtin_arm_sadd16(a, b); + x = __builtin_arm_sasx(a, b); + x = __builtin_arm_shadd16(a, b); + x = __builtin_arm_shasx(a, b); + x = __builtin_arm_shsax(a, b); + x = __builtin_arm_shsub16(a, b); + x = __builtin_arm_ssax(a, b); + x = __builtin_arm_ssub16(a, b); + + y = __builtin_arm_uadd16(c, d); + y = __builtin_arm_uasx(c, d); + y = __builtin_arm_uhadd16(c, d); + y = __builtin_arm_uhasx(c, d); + y = __builtin_arm_uhsax(c, d); + y = __builtin_arm_uhsub16(c, d); + y = __builtin_arm_uqadd16(c, d); + y = __builtin_arm_uqasx(c, d); + y = __builtin_arm_uqsax(c, d); + y = __builtin_arm_uqsub16(c, d); + y = __builtin_arm_usax(c, d); + y = __builtin_arm_usub16(c, d); +} + +void test_9_5_10_parallel_16bit_multiplication(int16x2_t a, int16x2_t b, + int32_t c, int64_t d) { + int32_t x; + int64_t y; + + x = __builtin_arm_smlad(a, b, c); + x = __builtin_arm_smladx(a, b, c); + y = __builtin_arm_smlald(a, b, d); + y = __builtin_arm_smlaldx(a, b, d); + x = __builtin_arm_smlsd(a, b, c); + x = __builtin_arm_smlsdx(a, b, c); + y = __builtin_arm_smlsld(a, b, d); + y = __builtin_arm_smlsldx(a, b, d); + x = __builtin_arm_smuad(a, b); + x = __builtin_arm_smuadx(a, b); + x = __builtin_arm_smusd(a, b); + x = __builtin_arm_smusdx(a, b); +} diff --git a/test/Sema/c2x-fallthrough.c b/test/Sema/c2x-fallthrough.c new file mode 100644 index 000000000000..2fd69c4da0f2 --- /dev/null +++ b/test/Sema/c2x-fallthrough.c @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s + +void f(int n) { + switch (n) { + case 0: + n += 1; + [[fallthrough]]; // ok + case 1: + if (n) { + [[fallthrough]]; // ok + } else { + return; + } + case 2: + for (int n = 0; n != 10; ++n) + [[fallthrough]]; // expected-error {{does not directly precede switch label}} + case 3: + while (1) + [[fallthrough]]; // expected-error {{does not directly precede switch label}} + case 4: + while (0) + [[fallthrough]]; // expected-error {{does not directly precede switch label}} + case 5: + do [[fallthrough]]; while (1); // expected-error {{does not directly precede switch label}} + case 6: + do [[fallthrough]]; while (0); // expected-error {{does not directly precede switch label}} + case 7: + switch (n) { + case 0: + // FIXME: This should be an error, even though the next thing we do is to + // fall through in an outer switch statement. + [[fallthrough]]; + } + case 8: + [[fallthrough]]; // expected-error {{does not directly precede switch label}} + goto label; + label: + case 9: + n += 1; + case 10: // no warning, -Wimplicit-fallthrough is not enabled in this test, and does not need to + // be enabled for these diagnostics to be produced. + break; + } +} + +[[fallthrough]] typedef int n1; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} +typedef int [[fallthrough]] n2; // expected-error {{'fallthrough' attribute cannot be applied to types}} +typedef int n3 [[fallthrough]]; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} + +enum [[fallthrough]] E { // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} + One +}; +struct [[fallthrough]] S { // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} + int i; +}; + +[[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} +void g(void) { + [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}} + [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}} + + switch (n) { + // FIXME: This should be an error. + [[fallthrough]]; + return; + + case 0: + [[fallthrough, fallthrough]]; // expected-error {{multiple times}} + case 1: + [[fallthrough(0)]]; // expected-error {{argument list}} + case 2: + break; + } +} + diff --git a/test/Sema/c2x-maybe_unused-errors.c b/test/Sema/c2x-maybe_unused-errors.c new file mode 100644 index 000000000000..68150dded9d5 --- /dev/null +++ b/test/Sema/c2x-maybe_unused-errors.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s + +struct [[maybe_unused]] S1 { // ok + int a [[maybe_unused]]; +}; +struct [[maybe_unused maybe_unused]] S2 { // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}} + int a; +}; +struct [[maybe_unused("Wrong")]] S3 { // expected-error {{'maybe_unused' cannot have an argument list}} + int a; +}; + diff --git a/test/Sema/c2x-maybe_unused.c b/test/Sema/c2x-maybe_unused.c new file mode 100644 index 000000000000..816cf7835fa9 --- /dev/null +++ b/test/Sema/c2x-maybe_unused.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused -fdouble-square-bracket-attributes -verify %s + +struct [[maybe_unused]] S1 { // ok + int a [[maybe_unused]]; +}; + +enum [[maybe_unused]] E1 { + EnumVal [[maybe_unused]] +}; + +[[maybe_unused]] void unused_func([[maybe_unused]] int parm) { + typedef int maybe_unused_int [[maybe_unused]]; + [[maybe_unused]] int I; +} + +void f1(void) { + int x; // expected-warning {{unused variable}} + typedef int I; // expected-warning {{unused typedef 'I'}} + + // Should not warn about these due to not being used. + [[maybe_unused]] int y; + typedef int maybe_unused_int [[maybe_unused]]; + + // Should not warn about these uses. + struct S1 s; + maybe_unused_int test; + y = 12; +} + +void f2(void); +[[maybe_unused]] void f2(void); + +void f2(void) { +} + diff --git a/test/Sema/c2x-nodiscard.c b/test/Sema/c2x-nodiscard.c new file mode 100644 index 000000000000..fc5b12347e62 --- /dev/null +++ b/test/Sema/c2x-nodiscard.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s + +struct [[nodiscard]] S1 { // ok + int i; +}; +struct [[nodiscard nodiscard]] S2 { // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}} + int i; +}; +struct [[nodiscard("Wrong")]] S3 { // expected-error {{'nodiscard' cannot have an argument list}} + int i; +}; + +[[nodiscard]] int f1(void); +enum [[nodiscard]] E1 { One }; + +[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}} + +struct [[nodiscard]] S4 { + int i; +}; +struct S4 get_s(void); + +enum [[nodiscard]] E2 { Two }; +enum E2 get_e(void); + +[[nodiscard]] int get_i(); + +void f2(void) { + get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Okay, warnings are not encouraged + (void)get_s(); + (void)get_i(); + (void)get_e(); +} + +struct [[nodiscard]] error_info{ + int i; +}; + +struct error_info enable_missile_safety_mode(void); +void launch_missiles(void); +void test_missiles(void) { + enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} + launch_missiles(); +} + diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 887bce06306c..97586a7cc05e 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -77,7 +77,7 @@ int ints(long a, unsigned long b) { ((int) a == (unsigned int) B) + ((short) a == (unsigned short) B) + ((signed char) a == (unsigned char) B) + - (a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}} + (a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} (a < (unsigned int) B) + (a < (unsigned short) B) + (a < (unsigned char) B) + @@ -85,8 +85,8 @@ int ints(long a, unsigned long b) { ((int) a < B) + ((short) a < B) + ((signed char) a < B) + - ((long) a < (unsigned long) B) + // expected-warning {{comparison of integers of different signs}} - ((int) a < (unsigned int) B) + // expected-warning {{comparison of integers of different signs}} + ((long) a < (unsigned long) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} + ((int) a < (unsigned int) B) + // expected-warning {{comparison of unsigned expression < 0 is always false}} ((short) a < (unsigned short) B) + ((signed char) a < (unsigned char) B) + @@ -308,8 +308,59 @@ int rdar8414119_bar(unsigned x) { int rdar8511238() { enum A { A_foo, A_bar }; enum A a; + + if (a == 0) + return 0; + if (a != 0) + return 0; if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} - return 0; + return 0; + if (a <= 0) + return 0; + if (a > 0) + return 0; + if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + + if (0 == a) + return 0; + if (0 != a) + return 0; + if (0 < a) + return 0; + if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (0 >= a) + return 0; + + if (a == 0U) + return 0; + if (a != 0U) + return 0; + if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (a <= 0U) + return 0; + if (a > 0U) + return 0; + if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + + if (0U == a) + return 0; + if (0U != a) + return 0; + if (0U < a) + return 0; + if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (0U >= a) + return 0; + return 20; } diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c index 1b0a325dd188..d60296f27992 100644 --- a/test/Sema/const-eval.c +++ b/test/Sema/const-eval.c @@ -144,3 +144,11 @@ void *PR28739a = (__int128)(unsigned long)-1 + &PR28739a; void *PR28739b = &PR28739b + (__int128)(unsigned long)-1; __int128 PR28739c = (&PR28739c + (__int128)(unsigned long)-1) - &PR28739c; void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1]; + +struct PR35214_X { + int k; + int arr[]; +}; +int PR35214_x; +int PR35214_y = ((struct PR35214_X *)&PR35214_x)->arr[1]; // expected-error {{not a compile-time constant}} +int *PR35214_z = &((struct PR35214_X *)&PR35214_x)->arr[1]; // ok, &PR35214_x + 2 diff --git a/test/Sema/dllexport.c b/test/Sema/dllexport.c index 7991a455b4de..2e0fe0ce114a 100644 --- a/test/Sema/dllexport.c +++ b/test/Sema/dllexport.c @@ -5,17 +5,17 @@ // Invalid usage. __declspec(dllexport) typedef int typedef1; -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} typedef __declspec(dllexport) int typedef2; -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to}} typedef int __declspec(dllexport) typedef3; -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to}} typedef __declspec(dllexport) void (*FunTy)(); -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to}} enum __declspec(dllexport) Enum { EnumVal }; -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to}} struct __declspec(dllexport) Record {}; -// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllexport' attribute only applies to}} diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c index a7fb00e3f773..988a8e33a7ef 100644 --- a/test/Sema/dllimport.c +++ b/test/Sema/dllimport.c @@ -2,20 +2,21 @@ // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c11 -DMS %s // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c11 -DGNU %s // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 -DGNU %s +// RUN: %clang_cc1 -triple aarch64-win32 -fsyntax-only -fms-extensions -verify -std=c99 -DMS %s // Invalid usage. __declspec(dllimport) typedef int typedef1; -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} typedef __declspec(dllimport) int typedef2; -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to}} typedef int __declspec(dllimport) typedef3; -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to}} typedef __declspec(dllimport) void (*FunTy)(); -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to}} enum __declspec(dllimport) Enum { EnumVal }; -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to}} struct __declspec(dllimport) Record {}; -// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}} +// expected-warning@-1{{'dllimport' attribute only applies to}} @@ -210,9 +211,14 @@ __declspec(dllimport) void redecl6(); void redecl7(); __declspec(dllimport) inline void redecl7() {} -// PR31069: Don't crash trying to merge attributes for redeclaration of invalid decl. +// PR31069: Don't crash trying to merge attributes for redeclaration of invalid +// decl. void __declspec(dllimport) redecl8(unknowntype X); // expected-error{{unknown type name 'unknowntype'}} void redecl8(unknowntype X) { } // expected-error{{unknown type name 'unknowntype'}} +// PR32021: Similarly, don't crash trying to merge attributes from a valid +// decl to an invalid redeclaration. +void __declspec(dllimport) redecl9(void); // expected-note{{previous declaration is here}} +int redecl9(void) {} // expected-error{{conflicting types for 'redecl9'}} // External linkage is required. __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} diff --git a/test/Sema/enum-sign-conversion.c b/test/Sema/enum-sign-conversion.c new file mode 100644 index 000000000000..518fc670d314 --- /dev/null +++ b/test/Sema/enum-sign-conversion.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -DUNSIGNED -Wsign-conversion %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -verify -Wsign-conversion %s + +// PR35200 +enum X { A,B,C}; +int f(enum X x) { +#ifdef UNSIGNED + return x; // expected-warning {{implicit conversion changes signedness: 'enum X' to 'int'}} +#else + // expected-no-diagnostics + return x; +#endif +} diff --git a/test/Sema/enum.c b/test/Sema/enum.c index 3546bfe48fc6..f9e40690c6a6 100644 --- a/test/Sema/enum.c +++ b/test/Sema/enum.c @@ -123,3 +123,15 @@ int NegativeShortTest[NegativeShort == -1 ? 1 : -1]; // PR24610 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}} typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}} + +// PR28903 +// In C it is valid to define tags inside enums. +struct PR28903 { + enum { + PR28903_A = (enum { + PR28903_B, + PR28903_C = PR28903_B + })0 + }; + int makeStructNonEmpty; +}; diff --git a/test/Sema/error-type-safety.cpp b/test/Sema/error-type-safety.cpp new file mode 100644 index 000000000000..223645de0f71 --- /dev/null +++ b/test/Sema/error-type-safety.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define INT_TAG 42 + +static const int test_in + __attribute__((type_tag_for_datatype(test, int))) = INT_TAG; + +// Argument index: 1, Type tag index: 2 +void test_bounds_index(...) + __attribute__((argument_with_type_tag(test, 1, 2))); + +// Argument index: 3, Type tag index: 1 +void test_bounds_arg_index(...) + __attribute__((argument_with_type_tag(test, 3, 1))); + +void test_bounds() +{ + // Test the boundary edges (ensure no off-by-one) with argument indexing. + test_bounds_index(1, INT_TAG); + + test_bounds_index(1); // expected-error {{type tag index 2 is greater than the number of arguments specified}} + test_bounds_arg_index(INT_TAG, 1); // expected-error {{argument index 3 is greater than the number of arguments specified}} +} diff --git a/test/Sema/format-strings-fixit-ssize_t.c b/test/Sema/format-strings-fixit-ssize_t.c index 5208a294a480..f8893a14a412 100644 --- a/test/Sema/format-strings-fixit-ssize_t.c +++ b/test/Sema/format-strings-fixit-ssize_t.c @@ -1,7 +1,7 @@ // RUN: cp %s %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s /* This is a test of the various code modification hints that are provided as part of warning or extension diagnostics. All of the @@ -9,10 +9,14 @@ compile cleanly with -Werror -pedantic. */ int printf(char const *, ...); +int scanf(const char *, ...); void test() { typedef signed long int ssize_t; printf("%f", (ssize_t) 42); + ssize_t s; + scanf("%f", &s); } // CHECK: printf("%zd", (ssize_t) 42); +// CHECK: scanf("%zd", &s) diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c index 7a92842b2454..b7cdd7dd4a9a 100644 --- a/test/Sema/format-strings-scanf.c +++ b/test/Sema/format-strings-scanf.c @@ -1,10 +1,28 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s // Test that -Wformat=0 works: -// RUN: %clang_cc1 -fsyntax-only -Werror -Wformat=0 %s +// RUN: %clang_cc1 -std=c11 -fsyntax-only -Werror -Wformat=0 %s #include <stdarg.h> -typedef __typeof(sizeof(int)) size_t; +typedef __SIZE_TYPE__ size_t; +#define __SSIZE_TYPE__ \ + __typeof__(_Generic((__SIZE_TYPE__)0, \ + unsigned long long int : (long long int)0, \ + unsigned long int : (long int)0, \ + unsigned int : (int)0, \ + unsigned short : (short)0, \ + unsigned char : (signed char)0)) +typedef __SSIZE_TYPE__ ssize_t; + +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#define __UNSIGNED_PTRDIFF_TYPE__ \ + __typeof__(_Generic((__PTRDIFF_TYPE__)0, \ + long long int : (unsigned long long int)0, \ + long int : (unsigned long int)0, \ + int : (unsigned int)0, \ + short : (unsigned short)0, \ + signed char : (unsigned char)0)) + typedef struct _FILE FILE; typedef __WCHAR_TYPE__ wchar_t; @@ -172,6 +190,46 @@ void test_qualifiers(const int *cip, volatile int* vip, scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}} } +void test_size_types() { + size_t s = 0; + scanf("%zu", &s); // No warning. + + double d1 = 0.; + scanf("%zu", &d1); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}} + + ssize_t ss = 0; + scanf("%zd", &s); // No warning. + + double d2 = 0.; + scanf("%zd", &d2); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}} + + ssize_t sn = 0; + scanf("%zn", &sn); // No warning. + + double d3 = 0.; + scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}} +} + +void test_ptrdiff_t_types() { + __UNSIGNED_PTRDIFF_TYPE__ p1 = 0; + scanf("%tu", &p1); // No warning. + + double d1 = 0.; + scanf("%tu", &d1); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}} + + ptrdiff_t p2 = 0; + scanf("%td", &p2); // No warning. + + double d2 = 0.; + scanf("%td", &d2); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}} + + ptrdiff_t p3 = 0; + scanf("%tn", &p3); // No warning. + + double d3 = 0.; + scanf("%tn", &d3); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}} +} + void check_conditional_literal(char *s, int *i) { scanf(0 ? "%s" : "%d", i); // no warning scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}} diff --git a/test/Sema/fp16vec-sema.c b/test/Sema/fp16vec-sema.c new file mode 100644 index 000000000000..aefb5f86a14b --- /dev/null +++ b/test/Sema/fp16vec-sema.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef __fp16 half4 __attribute__ ((vector_size (8))); +typedef float float4 __attribute__ ((vector_size (16))); +typedef short short4 __attribute__ ((vector_size (8))); +typedef int int4 __attribute__ ((vector_size (16))); + +half4 hv0, hv1; +float4 fv0, fv1; +short4 sv0; +int4 iv0; + +void testFP16Vec(int c) { + hv0 = hv0 + hv1; + hv0 = hv0 - hv1; + hv0 = hv0 * hv1; + hv0 = hv0 / hv1; + hv0 = c ? hv0 : hv1; + hv0 += hv1; + hv0 -= hv1; + hv0 *= hv1; + hv0 /= hv1; + sv0 = hv0 == hv1; + sv0 = hv0 != hv1; + sv0 = hv0 < hv1; + sv0 = hv0 > hv1; + sv0 = hv0 <= hv1; + sv0 = hv0 >= hv1; + sv0 = hv0 || hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}} + sv0 = hv0 && hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}} + + // Implicit conversion between half vectors and float vectors are not allowed. + hv0 = fv0; // expected-error{{assigning to}} + fv0 = hv0; // expected-error{{assigning to}} + hv0 = (half4)fv0; // expected-error{{invalid conversion between}} + fv0 = (float4)hv0; // expected-error{{invalid conversion between}} + hv0 = fv0 + fv1; // expected-error{{assigning to}} + fv0 = hv0 + hv1; // expected-error{{assigning to}} + hv0 = hv0 + fv1; // expected-error{{cannot convert between vector}} + hv0 = c ? hv0 : fv1; // expected-error{{cannot convert between vector}} + sv0 = hv0 == fv1; // expected-error{{cannot convert between vector}} + sv0 = hv0 < fv1; // expected-error{{cannot convert between vector}} + sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} expected-error{{invalid operands to binary expression}} + iv0 = hv0 == hv1; // expected-error{{assigning to}} + + // FIXME: clang currently disallows using these operators on vectors, which is + // allowed by gcc. + sv0 = !hv0; // expected-error{{invalid argument type}} + hv0++; // expected-error{{cannot increment value of type}} + ++hv0; // expected-error{{cannot increment value of type}} +} diff --git a/test/Sema/implicit-decl-c90.c b/test/Sema/implicit-decl-c90.c new file mode 100644 index 000000000000..6b3491cff7cf --- /dev/null +++ b/test/Sema/implicit-decl-c90.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 %s -std=c90 -verify -fsyntax-only +void t0(int x) { + int explicit_decl(); + int (*p)(); + if(x > 0) + x = g() + 1; // expected-note {{previous implicit declaration}} + p = g; + if(x < 0) { + extern void u(int (*)[h()]); + int (*q)() = h; + } + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ +} + +void t1(int x) { + int (*p)(); + switch (x) { + g(); + case 0: + x = h() + 1; + break; + case 1: + p = g; + p = h; + break; + } + p = g; /* expected-error {{use of undeclared identifier 'g'}} */ + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ + explicit_decl(); + p = explicit_decl; +} + +int t2(int x) { + int y = ({ if (x > 0) x = g() + 1; 2*x; }); + int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */ + return y; +} + +int PR34822() { + {int i = sizeof(PR34822_foo());} /* expected-note {{previous definition is here}} */ + {extern int PR34822_foo;} /* expected-error {{redefinition of 'PR34822_foo' as different kind of symbol}} */ + + {extern int PR34822_bar;} /* expected-note {{previous declaration is here}} */ + {int i = sizeof(PR34822_bar());} /* expected-warning {{use of out-of-scope declaration of 'PR34822_bar' whose type is not compatible with that of an implicit declaration}} expected-error {{called object type 'int' is not a function or function pointer}} */ +} + +int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */ +int (*q)() = h; /* expected-error {{use of undeclared identifier 'h'}} */ + +float g(); /* expected-error {{conflicting types for 'g'}} */ diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c index ffab9a6f913c..a04bb0e22ef1 100644 --- a/test/Sema/implicit-decl.c +++ b/test/Sema/implicit-decl.c @@ -9,8 +9,7 @@ void func() { int32_t *vector[16]; const char compDesc[16 + 1]; int32_t compCount = 0; - if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \ - expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} + if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} expected-note {{previous implicit declaration}} } printg("Hello, World!\n"); // expected-error{{implicit declaration of function 'printg' is invalid in C99}} \ @@ -18,7 +17,7 @@ void func() { __builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}} } -Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}} +Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error {{conflicting types}} return 0; } diff --git a/test/Sema/inline-asm-validate-amdgpu.cl b/test/Sema/inline-asm-validate-amdgpu.cl index d60b09e0ce9d..bc2580c5738b 100644 --- a/test/Sema/inline-asm-validate-amdgpu.cl +++ b/test/Sema/inline-asm-validate-amdgpu.cl @@ -1,6 +1,7 @@ // REQUIRES: amdgpu-registered-target -// RUN: %clang_cc1 -x cl -triple amdgcn -fsyntax-only %s -// expected-no-diagnostics +// RUN: %clang_cc1 -triple amdgcn -fsyntax-only -verify %s + +#pragma OPENCL EXTENSION cl_khr_fp64 : enable kernel void test () { @@ -9,6 +10,67 @@ kernel void test () { // sgpr constraints __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "s" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exe" (imm) : ); // expected-error {{invalid input constraint '{exe' in asm}} + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec" (imm) : ); // expected-error {{invalid input constraint '{exec' in asm}} + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}a" (imm) : ); // expected-error {{invalid input constraint '{exec}a' in asm}} + // vgpr constraints __asm__ ("v_mov_b32 %0, %1" : "=v" (vgpr) : "v" (imm) : ); } + +__kernel void +test_float(const __global float *a, const __global float *b, __global float *c, unsigned i) +{ + float ai = a[i]; + float bi = b[i]; + float ci; + + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : ""(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "="(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={va}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={va}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}a"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1}a' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "=v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=v1}' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1]' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v[a]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[a]}' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "=v"(ci) : "v"(ai), "v"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : "=v1"(ci) : "v2"(ai), "v3"(bi) : ); /// expected-error {{invalid output constraint '=v1' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{a}"(ai), "{v3}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{a}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}} + c[i] = ci; +} + +__kernel void +test_double(const __global double *a, const __global double *b, __global double *c, unsigned i) +{ + double ai = a[i]; + double bi = b[i]; + double ci; + + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v{[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '=v{[1:2]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]a}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]a}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}a"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]}a' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[:2]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[2:1]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[2:1]}' in asm}} + + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v[1:2]"(ci) : "v[3:4]"(ai), "v[5:6]"(bi) : ); //expected-error {{invalid output constraint '=v[1:2]' in asm}} + + c[i] = ci; +} diff --git a/test/Sema/internal_linkage.c b/test/Sema/internal_linkage.c index f4deccca63d1..37090a333315 100644 --- a/test/Sema/internal_linkage.c +++ b/test/Sema/internal_linkage.c @@ -15,7 +15,7 @@ int var5 __attribute__((internal_linkage)); // expected-error{{'internal_linkage int var5 __attribute__((common)); // expected-note{{conflicting attribute is here}} __attribute__((internal_linkage)) int f() {} -struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables and functions}} +struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}} }; __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}} diff --git a/test/Sema/ms-annotation.c b/test/Sema/ms-annotation.c new file mode 100644 index 000000000000..9a2beebf065a --- /dev/null +++ b/test/Sema/ms-annotation.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple i686-windows %s -verify -fms-extensions +// RUN: %clang_cc1 -x c++ -std=c++11 -triple i686-windows %s -verify -fms-extensions +// RUN: %clang_cc1 -x c++ -std=c++14 -triple i686-windows %s -verify -fms-extensions + +void test1(void) { + __annotation(); // expected-error {{too few arguments to function call, expected at least 1, have 0}} + __annotation(1); // expected-error {{must be wide string constants}} + __annotation(L"a1"); + __annotation(L"a1", L"a2"); + __annotation(L"a1", L"a2", 42); // expected-error {{must be wide string constants}} + __annotation(L"a1", L"a2", L"a3"); + __annotation(L"multi " L"part " L"string"); +} diff --git a/test/Sema/ms-inline-asm.c b/test/Sema/ms-inline-asm.c index 952112ea8cf8..3fc74fa99c35 100644 --- a/test/Sema/ms-inline-asm.c +++ b/test/Sema/ms-inline-asm.c @@ -59,18 +59,13 @@ int t2(int *arr, int i) { mov eax, arr[1 + (2 * 5) - 3 + 1<<1]; } - // expected-error@+1 {{cannot use base register with variable reference}} - __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] } - // expected-error@+1 {{cannot use index register with variable reference}} - __asm { mov eax, arr[esi * 4] } // expected-error@+1 {{cannot use more than one symbol in memory operand}} __asm { mov eax, arr[i] } // expected-error@+1 {{cannot use more than one symbol in memory operand}} __asm { mov eax, global[i] } - // FIXME: Why don't we diagnose this? - // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}} - //__asm mov eax, [arr + i]; + // expected-error@+1 {{cannot use more than one symbol in memory operand}} + __asm mov eax, [arr + i]; return 0; } @@ -98,7 +93,7 @@ void t4() { __asm { mov eax, fs:[0] A.a } __asm { mov eax, fs:[0].A.a } __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}} - __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}} + __asm { mov eax, fs:[0]. A.a } // expected-error {{unexpected token in argument list}} } void test_operand_size() { diff --git a/test/Sema/noescape.c b/test/Sema/noescape.c new file mode 100644 index 000000000000..39f3f6f542ac --- /dev/null +++ b/test/Sema/noescape.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void escapefunc(int *); +void noescapefunc(__attribute__((noescape)) int *); +void (*escapefuncptr)(int *); +void (*noescapefuncptr)(__attribute__((noescape)) int *); + +void func_ne(__attribute__((noescape)) int *, int *); +void func_en(int *, __attribute__((noescape)) int *); + +void (*funcptr_ee)(int *, int *); +void (*funcptr_nn)(__attribute__((noescape)) int *, __attribute__((noescape)) int *); + +void test0(int c) { + escapefuncptr = &escapefunc; + escapefuncptr = &noescapefunc; + noescapefuncptr = &escapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}} + noescapefuncptr = &noescapefunc; + + escapefuncptr = c ? &escapefunc : &noescapefunc; + noescapefuncptr = c ? &escapefunc : &noescapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}} + + funcptr_ee = c ? &func_ne : &func_en; + funcptr_nn = c ? &func_ne : &func_en; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *, __attribute__((noescape)) int *)' from 'void (*)(int *, int *)'}} +} diff --git a/test/Sema/nonnull.c b/test/Sema/nonnull.c index 217bbb16df60..b589bb3d1ffd 100644 --- a/test/Sema/nonnull.c +++ b/test/Sema/nonnull.c @@ -37,7 +37,7 @@ int test_int_returns_nonnull(void) __attribute__((returns_nonnull)); // expected void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}} -int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}} +int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to Objective-C methods and functions}} void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning diff --git a/test/Sema/outof-range-constant-compare.c b/test/Sema/outof-range-constant-compare.c index 4b1637c46c5e..ccb55e4a1663 100644 --- a/test/Sema/outof-range-constant-compare.c +++ b/test/Sema/outof-range-constant-compare.c @@ -6,6 +6,7 @@ int value(void); int main() { int a = value(); + if (a == 0x1234567812345678L) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'int' is always false}} return 0; if (a != 0x1234567812345678L) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'int' is always true}} @@ -74,6 +75,7 @@ int main() return 0; if (0x1234567812345678L >= s) // expected-warning {{comparison of constant 1311768465173141112 with expression of type 'short' is always true}} return 0; + long l = value(); if (l == 0x1234567812345678L) return 0; @@ -101,40 +103,6 @@ int main() if (0x1234567812345678L >= l) return 0; - unsigned un = 0; - if (un == 0x0000000000000000L) - return 0; - if (un != 0x0000000000000000L) - return 0; - if (un < 0x0000000000000000L) - return 0; - if (un <= 0x0000000000000000L) - return 0; - if (un > 0x0000000000000000L) - return 0; - if (un >= 0x0000000000000000L) - return 0; - - if (0x0000000000000000L == un) - return 0; - if (0x0000000000000000L != un) - return 0; - if (0x0000000000000000L < un) - return 0; - if (0x0000000000000000L <= un) - return 0; - if (0x0000000000000000L > un) - return 0; - if (0x0000000000000000L >= un) - return 0; - float fl = 0; - if (fl == 0x0000000000000000L) // no warning - return 0; - - float dl = 0; - if (dl == 0x0000000000000000L) // no warning - return 0; - enum E { yes, no, diff --git a/test/Sema/outof-range-enum-constant-compare.c b/test/Sema/outof-range-enum-constant-compare.c new file mode 100644 index 000000000000..b9ce08f68c0e --- /dev/null +++ b/test/Sema/outof-range-enum-constant-compare.c @@ -0,0 +1,379 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s + +int main() { + enum A { A_a = 2 }; + enum A a; + +#ifdef SILENCE + // expected-no-diagnostics +#endif + +#ifdef UNSIGNED +#ifndef SILENCE + if (a < 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296 >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a > 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296 <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (a <= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296 > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a >= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296 < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (a == 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296 != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a != 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296 == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + + if (a < 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296U >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a > 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296U <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (a <= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296U > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a >= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296U < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (a == 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; + if (4294967296U != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (a != 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}} + return 0; + if (4294967296U == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}} + return 0; +#else // SILENCE + if (a < 4294967296) + return 0; + if (4294967296 >= a) + return 0; + if (a > 4294967296) + return 0; + if (4294967296 <= a) + return 0; + if (a <= 4294967296) + return 0; + if (4294967296 > a) + return 0; + if (a >= 4294967296) + return 0; + if (4294967296 < a) + return 0; + if (a == 4294967296) + return 0; + if (4294967296 != a) + return 0; + if (a != 4294967296) + return 0; + if (4294967296 == a) + return 0; + + if (a < 4294967296U) + return 0; + if (4294967296U >= a) + return 0; + if (a > 4294967296U) + return 0; + if (4294967296U <= a) + return 0; + if (a <= 4294967296U) + return 0; + if (4294967296U > a) + return 0; + if (a >= 4294967296U) + return 0; + if (4294967296U < a) + return 0; + if (a == 4294967296U) + return 0; + if (4294967296U != a) + return 0; + if (a != 4294967296U) + return 0; + if (4294967296U == a) + return 0; +#endif +#elif defined(SIGNED) +#ifndef SILENCE + if (a < -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + if (-2147483649 >= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + if (a > -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (-2147483649 <= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (a <= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + if (-2147483649 > a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + if (a >= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (-2147483649 < a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (a == -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + if (-2147483649 != a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (a != -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}} + return 0; + if (-2147483649 == a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}} + return 0; + + if (a < 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (2147483648 >= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (a > 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; + if (2147483648 <= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; + if (a <= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (2147483648 > a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (a >= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; + if (2147483648 < a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; + if (a == 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; + if (2147483648 != a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (a != 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}} + return 0; + if (2147483648 == a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}} + return 0; +#else // SILENCE + if (a < -2147483649) + return 0; + if (-2147483649 >= a) + return 0; + if (a > -2147483649) + return 0; + if (-2147483649 <= a) + return 0; + if (a <= -2147483649) + return 0; + if (-2147483649 > a) + return 0; + if (a >= -2147483649) + return 0; + if (-2147483649 < a) + return 0; + if (a == -2147483649) + return 0; + if (-2147483649 != a) + return 0; + if (a != -2147483649) + return 0; + if (-2147483649 == a) + return 0; + + if (a < 2147483648) + return 0; + if (2147483648 >= a) + return 0; + if (a > 2147483648) + return 0; + if (2147483648 <= a) + return 0; + if (a <= 2147483648) + return 0; + if (2147483648 > a) + return 0; + if (a >= 2147483648) + return 0; + if (2147483648 < a) + return 0; + if (a == 2147483648) + return 0; + if (2147483648 != a) + return 0; + if (a != 2147483648) + return 0; + if (2147483648 == a) + return 0; +#endif +#endif +} + +// https://bugs.llvm.org/show_bug.cgi?id=35009 +int PR35009() { + enum A { A_a = 2 }; + enum A a; + + // in C, this should not warn. + + if (a < 1) + return 0; + if (1 >= a) + return 0; + if (a > 1) + return 0; + if (1 <= a) + return 0; + if (a <= 1) + return 0; + if (1 > a) + return 0; + if (a >= 1) + return 0; + if (1 < a) + return 0; + if (a == 1) + return 0; + if (1 != a) + return 0; + if (a != 1) + return 0; + if (1 == a) + return 0; + + if (a < 1U) + return 0; + if (1U >= a) + return 0; + if (a > 1U) + return 0; + if (1U <= a) + return 0; + if (a <= 1U) + return 0; + if (1U > a) + return 0; + if (a >= 1U) + return 0; + if (1U < a) + return 0; + if (a == 1U) + return 0; + if (1U != a) + return 0; + if (a != 1U) + return 0; + if (1U == a) + return 0; + + if (a < 2) + return 0; + if (2 >= a) + return 0; + if (a > 2) + return 0; + if (2 <= a) + return 0; + if (a <= 2) + return 0; + if (2 > a) + return 0; + if (a >= 2) + return 0; + if (2 < a) + return 0; + if (a == 2) + return 0; + if (2 != a) + return 0; + if (a != 2) + return 0; + if (2 == a) + return 0; + + if (a < 2U) + return 0; + if (2U >= a) + return 0; + if (a > 2U) + return 0; + if (2U <= a) + return 0; + if (a <= 2U) + return 0; + if (2U > a) + return 0; + if (a >= 2U) + return 0; + if (2U < a) + return 0; + if (a == 2U) + return 0; + if (2U != a) + return 0; + if (a != 2U) + return 0; + if (2U == a) + return 0; + + if (a < 3) + return 0; + if (3 >= a) + return 0; + if (a > 3) + return 0; + if (3 <= a) + return 0; + if (a <= 3) + return 0; + if (3 > a) + return 0; + if (a >= 3) + return 0; + if (3 < a) + return 0; + if (a == 3) + return 0; + if (3 != a) + return 0; + if (a != 3) + return 0; + if (3 == a) + return 0; + + if (a < 3U) + return 0; + if (3U >= a) + return 0; + if (a > 3U) + return 0; + if (3U <= a) + return 0; + if (a <= 3U) + return 0; + if (3U > a) + return 0; + if (a >= 3U) + return 0; + if (3U < a) + return 0; + if (a == 3U) + return 0; + if (3U != a) + return 0; + if (a != 3U) + return 0; + if (3U == a) + return 0; + + return 1; +} diff --git a/test/Sema/pointer-addition.c b/test/Sema/pointer-addition.c index c71e96114b8a..562f05340f7c 100644 --- a/test/Sema/pointer-addition.c +++ b/test/Sema/pointer-addition.c @@ -1,4 +1,8 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11 +// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c11 +// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify -pedantic -Wextra -std=c11 +// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify -pedantic -Wextra -std=c11 + +#include <stdint.h> typedef struct S S; // expected-note 4 {{forward declaration of 'struct S'}} extern _Atomic(S*) e; @@ -20,4 +24,9 @@ void a(S* b, void* c) { d -= 1; // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' (aka 'void (struct S *, void *)') is a GNU extension}} (void)(1 + d); // expected-warning {{arithmetic on a pointer to the function type 'void (S *, void *)' (aka 'void (struct S *, void *)') is a GNU extension}} e++; // expected-error {{arithmetic on a pointer to an incomplete type}} + intptr_t i = (intptr_t)b; + char *f = (char*)0 + i; // expected-warning {{arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension}} + // Cases that don't match the GNU inttoptr idiom get a different warning. + f = (char*)0 - i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}} + int *g = (int*)0 + i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}} } diff --git a/test/Sema/pragma-ms_struct.c b/test/Sema/pragma-ms_struct.c index a2591b6a4c44..e10d49e6761c 100644 --- a/test/Sema/pragma-ms_struct.c +++ b/test/Sema/pragma-ms_struct.c @@ -25,7 +25,7 @@ struct { } __attribute__((__ms_struct__)) t1; struct S { - double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to struct or union}} + double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to structs, unions, and classes}} unsigned long bf_1 : 12; unsigned long : 0; unsigned long bf_2 : 12; @@ -36,7 +36,7 @@ enum A = 0, B, C -} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct or union}} +} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to}} // rdar://10513599 #pragma ms_struct on diff --git a/test/Sema/pragma-pack.c b/test/Sema/pragma-pack.c index e93ce42148ca..2ed0874bfd2d 100644 --- a/test/Sema/pragma-pack.c +++ b/test/Sema/pragma-pack.c @@ -25,3 +25,8 @@ #pragma pack(pop, 16) /* expected-warning {{value of #pragma pack(show) == 16}} */ #pragma pack(show) + +// Warn about unbalanced pushes. +#pragma pack (push,4) // expected-warning {{unterminated '#pragma pack (push, ...)' at end of file}} +#pragma pack (push) // expected-warning {{unterminated '#pragma pack (push, ...)' at end of file}} +#pragma pack () // expected-note {{did you intend to use '#pragma pack (pop)' instead of '#pragma pack()'?}} diff --git a/test/Sema/preserve-call-conv.c b/test/Sema/preserve-call-conv.c index f258f45ac582..6bd049ffdca2 100644 --- a/test/Sema/preserve-call-conv.c +++ b/test/Sema/preserve-call-conv.c @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify // RUN: %clang_cc1 %s -fsyntax-only -triple arm64-unknown-unknown -verify +// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-windows-msvc -verify +// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-unknown-windows-msvc -verify + typedef void typedef_fun_t(int); void __attribute__((preserve_most)) foo(void *ptr) { diff --git a/test/Sema/sign-compare-enum.c b/test/Sema/sign-compare-enum.c new file mode 100644 index 000000000000..8661bd502fe5 --- /dev/null +++ b/test/Sema/sign-compare-enum.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify -Wsign-compare %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify -Wsign-compare %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -verify %s + +int main() { + enum A { A_a = 0, A_b = 1 }; + static const int message[] = {0, 1}; + enum A a; + + if (a < 2) + return 0; + +#if defined(SIGNED) && !defined(SILENCE) + if (a < sizeof(message)/sizeof(message[0])) // expected-warning {{comparison of integers of different signs: 'enum A' and 'unsigned long long'}} + return 0; +#else + // expected-no-diagnostics + if (a < 2U) + return 0; + if (a < sizeof(message)/sizeof(message[0])) + return 0; +#endif +} diff --git a/test/Sema/struct-packed-align.c b/test/Sema/struct-packed-align.c index abdcd8e6b9eb..aeba8d6fd938 100644 --- a/test/Sema/struct-packed-align.c +++ b/test/Sema/struct-packed-align.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify // RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify +// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-scei-ps4 -verify // Packed structs. struct s { @@ -146,13 +147,24 @@ extern int n2[__alignof(struct nS) == 1 ? 1 : -1]; // See the documentation of -Wpacked-bitfield-compat for more information. struct packed_chars { char a:4; +#ifdef __ORBIS__ + // Test for pre-r254596 clang behavior on the PS4 target. PS4 must maintain + // ABI backwards compatibility. + char b:8 __attribute__ ((packed)); + // expected-warning@-1 {{'packed' attribute ignored for field of type 'char'}} + char c:4; +#else char b:8 __attribute__ ((packed)); // expected-warning@-1 {{'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang}} char c:4; +#endif }; -#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1. +#if (defined(_WIN32) || defined(__ORBIS__)) && !defined(__declspec) // _MSC_VER is unavailable in cc1. // On Windows clang uses MSVC compatible layout in this case. +// +// Additionally, test for pre-r254596 clang behavior on the PS4 target. PS4 +// must maintain ABI backwards compatibility. extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1]; extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1]; #else diff --git a/test/Sema/suspicious-pragma-pack.c b/test/Sema/suspicious-pragma-pack.c new file mode 100644 index 000000000000..d7c5faf06910 --- /dev/null +++ b/test/Sema/suspicious-pragma-pack.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DSAFE -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DSAFE -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DRESET_HERE -DSAFE -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DRESET_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_FIRST_HEADER -DWARN_MODIFIED_HEADER -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_SECOND_HEADER -DWARN_MODIFIED_HEADER -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_HERE -DPUSH_SET_HERE -DSET_FIRST_HEADER -DSET_SECOND_HEADER -DWARN_MODIFIED_HEADER -verify %s + +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_POP_FIRST_HEADER -DSAFE -verify %s + +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -DNO_RECORD_2 -DSAFE -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack-suspicious-include -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -verify %s +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -Wpragma-pack -Wno-pragma-pack-suspicious-include -I %S/Inputs -DPUSH_SET_HERE -DNO_RECORD_1 -DSAFE -verify %s + +#ifdef SAFE +// expected-no-diagnostics +#endif + +#ifdef PUSH_HERE +#pragma pack (push) +#endif + +#ifdef PUSH_SET_HERE +#pragma pack (push, 4) +#ifndef SAFE +// expected-note@-2 {{previous '#pragma pack' directive that modifies alignment is here}} +// expected-warning@+9 {{non-default #pragma pack value changes the alignment of struct or union members in the included file}} +#endif +#endif + +#ifdef RESET_HERE +#pragma pack (4) +#pragma pack () // no warning after reset as the value is default. +#endif + +#include "pragma-pack1.h" + +#ifdef WARN_MODIFIED_HEADER +// expected-warning@-3 {{the current #pragma pack aligment value is modified in the included file}} +#endif + +#ifdef PUSH_SET_HERE +#pragma pack (pop) +#endif + +#ifdef PUSH_HERE +#pragma pack (pop) +#endif diff --git a/test/Sema/switch.c b/test/Sema/switch.c index 7aa695d7cb91..a33300b41f54 100644 --- a/test/Sema/switch.c +++ b/test/Sema/switch.c @@ -372,6 +372,7 @@ void switch_on_ExtendedEnum1(enum ExtendedEnum1 e) { case EE1_b: break; case EE1_c: break; // no-warning case EE1_d: break; // expected-warning {{case value not in enumerated type 'enum ExtendedEnum1'}} + // expected-warning@-1 {{comparison of two values with different enumeration types in switch statement ('enum ExtendedEnum1' and 'const enum ExtendedEnum1_unrelated')}} } } diff --git a/test/Sema/tautological-constant-compare.c b/test/Sema/tautological-constant-compare.c new file mode 100644 index 000000000000..c48aa9944453 --- /dev/null +++ b/test/Sema/tautological-constant-compare.c @@ -0,0 +1,585 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -DTEST -verify %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wno-tautological-constant-compare -verify %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -DTEST -verify -x c++ %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wno-tautological-constant-compare -verify -x c++ %s + +int value(void); + +#define macro(val) val + +#ifdef __cplusplus +template<typename T> +void TFunc() { + // Make sure that we do warn for normal variables in template functions ! + unsigned char c = value(); +#ifdef TEST + if (c > 255) // expected-warning {{comparison 'unsigned char' > 255 is always false}} + return; +#else + if (c > 255) + return; +#endif + + if (c > macro(255)) + return; + + T v = value(); + if (v > 255) + return; + if (v > 32767) + return; +} +#endif + +int main() +{ +#ifdef __cplusplus + TFunc<unsigned char>(); + TFunc<signed short>(); +#endif + + short s = value(); + +#ifdef TEST + if (s == 32767) + return 0; + if (s != 32767) + return 0; + if (s < 32767) + return 0; + if (s <= 32767) // expected-warning {{comparison 'short' <= 32767 is always true}} + return 0; + if (s > 32767) // expected-warning {{comparison 'short' > 32767 is always false}} + return 0; + if (s >= 32767) + return 0; + + if (32767 == s) + return 0; + if (32767 != s) + return 0; + if (32767 < s) // expected-warning {{comparison 32767 < 'short' is always false}} + return 0; + if (32767 <= s) + return 0; + if (32767 > s) + return 0; + if (32767 >= s) // expected-warning {{comparison 32767 >= 'short' is always true}} + return 0; + + // FIXME: assumes two's complement + if (s == -32768) + return 0; + if (s != -32768) + return 0; + if (s < -32768) // expected-warning {{comparison 'short' < -32768 is always false}} + return 0; + if (s <= -32768) + return 0; + if (s > -32768) + return 0; + if (s >= -32768) // expected-warning {{comparison 'short' >= -32768 is always true}} + return 0; + + if (-32768 == s) + return 0; + if (-32768 != s) + return 0; + if (-32768 < s) + return 0; + if (-32768 <= s) // expected-warning {{comparison -32768 <= 'short' is always true}} + return 0; + if (-32768 > s) // expected-warning {{comparison -32768 > 'short' is always false}} + return 0; + if (-32768 >= s) + return 0; + + // Note: both sides are promoted to unsigned long prior to the comparison, so + // it is perfectly possible for a short to compare greater than 32767UL. + if (s == 32767UL) + return 0; + if (s != 32767UL) + return 0; + if (s < 32767UL) + return 0; + if (s <= 32767UL) + return 0; + if (s > 32767UL) + return 0; + if (s >= 32767UL) + return 0; + + if (32767UL == s) + return 0; + if (32767UL != s) + return 0; + if (32767UL < s) + return 0; + if (32767UL <= s) + return 0; + if (32767UL > s) + return 0; + if (32767UL >= s) + return 0; + + if (s == 0UL) + return 0; + if (s != 0UL) + return 0; + if (s < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}} + return 0; + if (s <= 0UL) + return 0; + if (s > 0UL) + return 0; + if (s >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}} + return 0; + + if (0UL == s) + return 0; + if (0UL != s) + return 0; + if (0UL < s) + return 0; + if (0UL <= s) // expected-warning {{comparison of 0 <= unsigned expression is always true}} + return 0; + if (0UL > s) // expected-warning {{comparison of 0 > unsigned expression is always false}} + return 0; + if (0UL >= s) + return 0; + + enum { ULONG_MAX = (2UL * (unsigned long)__LONG_MAX__ + 1UL) }; + if (s == 2UL * (unsigned long)__LONG_MAX__ + 1UL) + return 0; + if (s != 2UL * (unsigned long)__LONG_MAX__ + 1UL) + return 0; + if (s < 2UL * (unsigned long)__LONG_MAX__ + 1UL) + return 0; + if (s <= 2UL * (unsigned long)__LONG_MAX__ + 1UL) // expected-warning-re {{comparison 'short' <= {{.*}} is always true}} + return 0; + if (s > 2UL * (unsigned long)__LONG_MAX__ + 1UL) // expected-warning-re {{comparison 'short' > {{.*}} is always false}} + return 0; + if (s >= 2UL * (unsigned long)__LONG_MAX__ + 1UL) + return 0; + + if (2UL * (unsigned long)__LONG_MAX__ + 1UL == s) + return 0; + if (2UL * (unsigned long)__LONG_MAX__ + 1UL != s) + return 0; + if (2UL * (unsigned long)__LONG_MAX__ + 1UL < s) // expected-warning-re {{comparison {{.*}} < 'short' is always false}} + return 0; + if (2UL * (unsigned long)__LONG_MAX__ + 1UL <= s) + return 0; + if (2UL * (unsigned long)__LONG_MAX__ + 1UL > s) + return 0; + if (2UL * (unsigned long)__LONG_MAX__ + 1UL >= s) // expected-warning-re {{comparison {{.*}} >= 'short' is always true}} + return 0; + + // FIXME: assumes two's complement + if (s == -32768L) + return 0; + if (s != -32768L) + return 0; + if (s < -32768L) // expected-warning {{comparison 'short' < -32768 is always false}} + return 0; + if (s <= -32768L) + return 0; + if (s > -32768L) + return 0; + if (s >= -32768L) // expected-warning {{comparison 'short' >= -32768 is always true}} + return 0; + + if (-32768L == s) + return 0; + if (-32768L != s) + return 0; + if (-32768L < s) + return 0; + if (-32768L <= s) // expected-warning {{comparison -32768 <= 'short' is always true}} + return 0; + if (-32768L > s) // expected-warning {{comparison -32768 > 'short' is always false}} + return 0; + if (-32768L >= s) + return 0; +#else + // expected-no-diagnostics + if (s == 32767) + return 0; + if (s != 32767) + return 0; + if (s < 32767) + return 0; + if (s <= 32767) + return 0; + if (s > 32767) + return 0; + if (s >= 32767) + return 0; + + if (32767 == s) + return 0; + if (32767 != s) + return 0; + if (32767 < s) + return 0; + if (32767 <= s) + return 0; + if (32767 > s) + return 0; + if (32767 >= s) + return 0; + + // FIXME: assumes two's complement + if (s == -32768) + return 0; + if (s != -32768) + return 0; + if (s < -32768) + return 0; + if (s <= -32768) + return 0; + if (s > -32768) + return 0; + if (s >= -32768) + return 0; + + if (-32768 == s) + return 0; + if (-32768 != s) + return 0; + if (-32768 < s) + return 0; + if (-32768 <= s) + return 0; + if (-32768 > s) + return 0; + if (-32768 >= s) + return 0; + + if (s == 32767UL) + return 0; + if (s != 32767UL) + return 0; + if (s < 32767UL) + return 0; + if (s <= 32767UL) + return 0; + if (s > 32767UL) + return 0; + if (s >= 32767UL) + return 0; + + if (32767UL == s) + return 0; + if (32767UL != s) + return 0; + if (32767UL < s) + return 0; + if (32767UL <= s) + return 0; + if (32767UL > s) + return 0; + if (32767UL >= s) + return 0; + + // FIXME: assumes two's complement + if (s == -32768L) + return 0; + if (s != -32768L) + return 0; + if (s < -32768L) + return 0; + if (s <= -32768L) + return 0; + if (s > -32768L) + return 0; + if (s >= -32768L) + return 0; + + if (-32768L == s) + return 0; + if (-32768L != s) + return 0; + if (-32768L < s) + return 0; + if (-32768L <= s) + return 0; + if (-32768L > s) + return 0; + if (-32768L >= s) + return 0; +#endif + + if (s == 0) + return 0; + if (s != 0) + return 0; + if (s < 0) + return 0; + if (s <= 0) + return 0; + if (s > 0) + return 0; + if (s >= 0) + return 0; + + if (0 == s) + return 0; + if (0 != s) + return 0; + if (0 < s) + return 0; + if (0 <= s) + return 0; + if (0 > s) + return 0; + if (0 >= s) + return 0; + + unsigned short us = value(); + +#ifdef TEST + if (us == 65535) + return 0; + if (us != 65535) + return 0; + if (us < 65535) + return 0; + if (us <= 65535) // expected-warning {{comparison 'unsigned short' <= 65535 is always true}} + return 0; + if (us > 65535) // expected-warning {{comparison 'unsigned short' > 65535 is always false}} + return 0; + if (us >= 65535) + return 0; + + if (65535 == us) + return 0; + if (65535 != us) + return 0; + if (65535 < us) // expected-warning {{comparison 65535 < 'unsigned short' is always false}} + return 0; + if (65535 <= us) + return 0; + if (65535 > us) + return 0; + if (65535 >= us) // expected-warning {{comparison 65535 >= 'unsigned short' is always true}} + return 0; + + if (us == 65535UL) + return 0; + if (us != 65535UL) + return 0; + if (us < 65535UL) + return 0; + if (us <= 65535UL) // expected-warning {{comparison 'unsigned short' <= 65535 is always true}} + return 0; + if (us > 65535UL) // expected-warning {{comparison 'unsigned short' > 65535 is always false}} + return 0; + if (us >= 65535UL) + return 0; + + if (65535UL == us) + return 0; + if (65535UL != us) + return 0; + if (65535UL < us) // expected-warning {{comparison 65535 < 'unsigned short' is always false}} + return 0; + if (65535UL <= us) + return 0; + if (65535UL > us) + return 0; + if (65535UL >= us) // expected-warning {{comparison 65535 >= 'unsigned short' is always true}} + return 0; +#else + // expected-no-diagnostics + if (us == 65535) + return 0; + if (us != 65535) + return 0; + if (us < 65535) + return 0; + if (us <= 65535) + return 0; + if (us > 65535) + return 0; + if (us >= 65535) + return 0; + + if (65535 == us) + return 0; + if (65535 != us) + return 0; + if (65535 < us) + return 0; + if (65535 <= us) + return 0; + if (65535 > us) + return 0; + if (65535 >= us) + return 0; + + if (us == 65535UL) + return 0; + if (us != 65535UL) + return 0; + if (us < 65535UL) + return 0; + if (us <= 65535UL) + return 0; + if (us > 65535UL) + return 0; + if (us >= 65535UL) + return 0; + + if (65535UL == us) + return 0; + if (65535UL != us) + return 0; + if (65535UL < us) + return 0; + if (65535UL <= us) + return 0; + if (65535UL > us) + return 0; + if (65535UL >= us) + return 0; +#endif + + if (us == 32767) + return 0; + if (us != 32767) + return 0; + if (us < 32767) + return 0; + if (us <= 32767) + return 0; + if (us > 32767) + return 0; + if (us >= 32767) + return 0; + + if (32767 == us) + return 0; + if (32767 != us) + return 0; + if (32767 < us) + return 0; + if (32767 <= us) + return 0; + if (32767 > us) + return 0; + if (32767 >= us) + return 0; + + if (us == 32767UL) + return 0; + if (us != 32767UL) + return 0; + if (us < 32767UL) + return 0; + if (us <= 32767UL) + return 0; + if (us > 32767UL) + return 0; + if (us >= 32767UL) + return 0; + + if (32767UL == us) + return 0; + if (32767UL != us) + return 0; + if (32767UL < us) + return 0; + if (32767UL <= us) + return 0; + if (32767UL > us) + return 0; + if (32767UL >= us) + return 0; + +#if __SIZEOF_INT128__ + __int128 i128; + if (i128 == -1) // used to crash + return 0; +#endif + + + enum E { + yes, + no, + maybe + }; + enum E e; + + if (e == yes) + return 0; + if (e != yes) + return 0; + if (e < yes) + return 0; + if (e <= yes) + return 0; + if (e > yes) + return 0; + if (e >= yes) + return 0; + + if (yes == e) + return 0; + if (yes != e) + return 0; + if (yes < e) + return 0; + if (yes <= e) + return 0; + if (yes > e) + return 0; + if (yes >= e) + return 0; + + if (e == maybe) + return 0; + if (e != maybe) + return 0; + if (e < maybe) + return 0; + if (e <= maybe) + return 0; + if (e > maybe) + return 0; + if (e >= maybe) + return 0; + + if (maybe == e) + return 0; + if (maybe != e) + return 0; + if (maybe < e) + return 0; + if (maybe <= e) + return 0; + if (maybe > e) + return 0; + if (maybe >= e) + return 0; + + // For the time being, use the declared type of bit-fields rather than their + // length when determining whether a value is in-range. + // FIXME: Reconsider this. + struct A { + int a : 3; + unsigned b : 3; + long c : 3; + unsigned long d : 3; + } a; + if (a.a < 3) {} + if (a.a < 4) {} + if (a.b < 7) {} + if (a.b < 8) {} + if (a.c < 3) {} + if (a.c < 4) {} + if (a.d < 7) {} + if (a.d < 8) {} + + return 1; +} diff --git a/test/Sema/tautological-constant-enum-compare.c b/test/Sema/tautological-constant-enum-compare.c new file mode 100644 index 000000000000..539439b817dc --- /dev/null +++ b/test/Sema/tautological-constant-enum-compare.c @@ -0,0 +1,406 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s + +int main() { + enum A { A_a = 2 }; + enum A a; + +#ifdef SILENCE + // expected-no-diagnostics +#else + // If we promote to unsigned, it doesn't matter whether the enum's underlying + // type was signed. + if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= a) + return 0; + if (a > 0U) + return 0; + if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0U) + return 0; + if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < a) + return 0; + + if (a < 4294967295U) + return 0; + if (4294967295U >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}} + return 0; + if (a > 4294967295U) // expected-warning {{comparison 'enum A' > 4294967295 is always false}} + return 0; + if (4294967295U <= a) + return 0; + if (a <= 4294967295U) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}} + return 0; + if (4294967295U > a) + return 0; + if (a >= 4294967295U) + return 0; + if (4294967295U < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}} + return 0; + + if (a < 2147483647U) + return 0; + if (2147483647U >= a) + return 0; + if (a > 2147483647U) + return 0; + if (2147483647U <= a) + return 0; + if (a <= 2147483647U) + return 0; + if (2147483647U > a) + return 0; + if (a >= 2147483647U) + return 0; + if (2147483647U < a) + return 0; +#endif + +#if defined(UNSIGNED) && !defined(SILENCE) + if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0 >= a) + return 0; + if (a > 0) + return 0; + if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0) + return 0; + if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0 < a) + return 0; + + if (a < 4294967295) + return 0; + if (4294967295 >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}} + return 0; + if (a > 4294967295) // expected-warning {{comparison 'enum A' > 4294967295 is always false}} + return 0; + if (4294967295 <= a) + return 0; + if (a <= 4294967295) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}} + return 0; + if (4294967295 > a) + return 0; + if (a >= 4294967295) + return 0; + if (4294967295 < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}} + return 0; +#else // SIGNED || SILENCE + if (a < 0) + return 0; + if (0 >= a) + return 0; + if (a > 0) + return 0; + if (0 <= a) + return 0; + if (a <= 0) + return 0; + if (0 > a) + return 0; + if (a >= 0) + return 0; + if (0 < a) + return 0; + +#ifndef SILENCE + if (a < 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}} + return 0; + if (4294967295 >= a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}} + return 0; + if (a > 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}} + return 0; + if (4294967295 <= a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}} + return 0; + if (a <= 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}} + return 0; + if (4294967295 > a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always true}} + return 0; + if (a >= 4294967295) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}} + return 0; + if (4294967295 < a) // expected-warning {{comparison of constant 4294967295 with expression of type 'enum A' is always false}} + return 0; +#else + if (a < 4294967295) + return 0; + if (4294967295 >= a) + return 0; + if (a > 4294967295) + return 0; + if (4294967295 <= a) + return 0; + if (a <= 4294967295) + return 0; + if (4294967295 > a) + return 0; + if (a >= 4294967295) + return 0; + if (4294967295 < a) + return 0; +#endif +#endif + +#if defined(SIGNED) && !defined(SILENCE) + if (a < -2147483648) // expected-warning {{comparison 'enum A' < -2147483648 is always false}} + return 0; + if (-2147483648 >= a) + return 0; + if (a > -2147483648) + return 0; + if (-2147483648 <= a) // expected-warning {{comparison -2147483648 <= 'enum A' is always true}} + return 0; + if (a <= -2147483648) + return 0; + if (-2147483648 > a) // expected-warning {{comparison -2147483648 > 'enum A' is always false}} + return 0; + if (a >= -2147483648) // expected-warning {{comparison 'enum A' >= -2147483648 is always true}} + return 0; + if (-2147483648 < a) + return 0; + + if (a < 2147483647) + return 0; + if (2147483647 >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}} + return 0; + if (a > 2147483647) // expected-warning {{comparison 'enum A' > 2147483647 is always false}} + return 0; + if (2147483647 <= a) + return 0; + if (a <= 2147483647) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}} + return 0; + if (2147483647 > a) + return 0; + if (a >= 2147483647) + return 0; + if (2147483647 < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}} + return 0; +#elif defined(UNSIGNED) && !defined(SILENCE) +#ifndef SILENCE + if (a < -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}} + return 0; + if (-2147483648 >= a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}} + return 0; + if (a > -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}} + return 0; + if (-2147483648 <= a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}} + return 0; + if (a <= -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}} + return 0; + if (-2147483648 > a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always false}} + return 0; + if (a >= -2147483648) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}} + return 0; + if (-2147483648 < a) // expected-warning {{comparison of constant -2147483648 with expression of type 'enum A' is always true}} + return 0; +#else + if (a < -2147483648) + return 0; + if (-2147483648 >= a) + return 0; + if (a > -2147483648) + return 0; + if (-2147483648 <= a) + return 0; + if (a <= -2147483648) + return 0; + if (-2147483648 > a) + return 0; + if (a >= -2147483648) + return 0; + if (-2147483648 < a) + return 0; +#endif + + if (a < 2147483647) + return 0; + if (2147483647 >= a) + return 0; + if (a > 2147483647) + return 0; + if (2147483647 <= a) + return 0; + if (a <= 2147483647) + return 0; + if (2147483647 > a) + return 0; + if (a >= 2147483647) + return 0; + if (2147483647 < a) + return 0; +#endif + + return 1; +} + +// https://bugs.llvm.org/show_bug.cgi?id=35009 +int PR35009() { + enum A { A_a = 2 }; + enum A a; + + // in C, this should not warn. + + if (a < 1) + return 0; + if (1 >= a) + return 0; + if (a > 1) + return 0; + if (1 <= a) + return 0; + if (a <= 1) + return 0; + if (1 > a) + return 0; + if (a >= 1) + return 0; + if (1 < a) + return 0; + if (a == 1) + return 0; + if (1 != a) + return 0; + if (a != 1) + return 0; + if (1 == a) + return 0; + + if (a < 1U) + return 0; + if (1U >= a) + return 0; + if (a > 1U) + return 0; + if (1U <= a) + return 0; + if (a <= 1U) + return 0; + if (1U > a) + return 0; + if (a >= 1U) + return 0; + if (1U < a) + return 0; + if (a == 1U) + return 0; + if (1U != a) + return 0; + if (a != 1U) + return 0; + if (1U == a) + return 0; + + if (a < 2) + return 0; + if (2 >= a) + return 0; + if (a > 2) + return 0; + if (2 <= a) + return 0; + if (a <= 2) + return 0; + if (2 > a) + return 0; + if (a >= 2) + return 0; + if (2 < a) + return 0; + if (a == 2) + return 0; + if (2 != a) + return 0; + if (a != 2) + return 0; + if (2 == a) + return 0; + + if (a < 2U) + return 0; + if (2U >= a) + return 0; + if (a > 2U) + return 0; + if (2U <= a) + return 0; + if (a <= 2U) + return 0; + if (2U > a) + return 0; + if (a >= 2U) + return 0; + if (2U < a) + return 0; + if (a == 2U) + return 0; + if (2U != a) + return 0; + if (a != 2U) + return 0; + if (2U == a) + return 0; + + if (a < 3) + return 0; + if (3 >= a) + return 0; + if (a > 3) + return 0; + if (3 <= a) + return 0; + if (a <= 3) + return 0; + if (3 > a) + return 0; + if (a >= 3) + return 0; + if (3 < a) + return 0; + if (a == 3) + return 0; + if (3 != a) + return 0; + if (a != 3) + return 0; + if (3 == a) + return 0; + + if (a < 3U) + return 0; + if (3U >= a) + return 0; + if (a > 3U) + return 0; + if (3U <= a) + return 0; + if (a <= 3U) + return 0; + if (3U > a) + return 0; + if (a >= 3U) + return 0; + if (3U < a) + return 0; + if (a == 3U) + return 0; + if (3U != a) + return 0; + if (a != 3U) + return 0; + if (3U == a) + return 0; + + return 1; +} diff --git a/test/Sema/tautological-unsigned-enum-zero-compare.c b/test/Sema/tautological-unsigned-enum-zero-compare.c new file mode 100644 index 000000000000..a32cfcd8329f --- /dev/null +++ b/test/Sema/tautological-unsigned-enum-zero-compare.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only \ +// RUN: -verify=unsigned,unsigned-signed %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only \ +// RUN: -verify=unsigned-signed %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only \ +// RUN: -Wno-tautological-unsigned-enum-zero-compare \ +// RUN: -verify=silence %s + +// Okay, this is where it gets complicated. +// Then default enum sigdness is target-specific. +// On windows, it is signed by default. We do not want to warn in that case. + +int main() { + enum A { A_a = 0 }; + enum A a; + enum B { B_a = -1 }; + enum B b; + + // silence-no-diagnostics + + if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0 >= a) + return 0; + if (a > 0) + return 0; + if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0) + return 0; + if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0 < a) + return 0; + + if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= a) + return 0; + if (a > 0U) + return 0; + if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0U) + return 0; + if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < a) + return 0; + + if (b < 0) + return 0; + if (0 >= b) + return 0; + if (b > 0) + return 0; + if (0 <= b) + return 0; + if (b <= 0) + return 0; + if (0 > b) + return 0; + if (b >= 0) + return 0; + if (0 < b) + return 0; + + if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= b) + return 0; + if (b > 0U) + return 0; + if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (b <= 0U) + return 0; + if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < b) + return 0; + + if (a == 0) + return 0; + if (0 != a) + return 0; + if (a != 0) + return 0; + if (0 == a) + return 0; + + if (a == 0U) + return 0; + if (0U != a) + return 0; + if (a != 0U) + return 0; + if (0U == a) + return 0; + + if (b == 0) + return 0; + if (0 != b) + return 0; + if (b != 0) + return 0; + if (0 == b) + return 0; + + if (b == 0U) + return 0; + if (0U != b) + return 0; + if (b != 0U) + return 0; + if (0U == b) + return 0; + + return 1; +} diff --git a/test/Sema/tautological-unsigned-enum-zero-compare.cpp b/test/Sema/tautological-unsigned-enum-zero-compare.cpp new file mode 100644 index 000000000000..a733b6edfc03 --- /dev/null +++ b/test/Sema/tautological-unsigned-enum-zero-compare.cpp @@ -0,0 +1,147 @@ +// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only \ +// RUN: -verify=unsigned,unsigned-signed %s +// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \ +// RUN: -verify=unsigned-signed %s +// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \ +// RUN: -Wno-tautological-unsigned-enum-zero-compare \ +// RUN: -verify=silence %s + +// silence-no-diagnostics + +int main() { + // On Windows, all enumerations have a fixed underlying type, which is 'int' + // if not otherwise specified, so A is identical to C on Windows. Otherwise, + // we follow the C++ rules, which say that the only valid values of A are 0 + // and 1. + enum A { A_foo = 0, A_bar, }; + enum A a; + + enum B : unsigned { B_foo = 0, B_bar, }; + enum B b; + + enum C : signed { C_foo = 0, C_bar, }; + enum C c; + + if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0 >= a) + return 0; + if (a > 0) + return 0; + if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0) + return 0; + if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0 < a) + return 0; + + // FIXME: As below, the issue here is that the enumeration is promoted to + // unsigned. + if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= a) + return 0; + if (a > 0U) + return 0; + if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (a <= 0U) + return 0; + if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < a) + return 0; + + if (b < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0 >= b) + return 0; + if (b > 0) + return 0; + if (0 <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (b <= 0) + return 0; + if (0 > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (b >= 0) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0 < b) + return 0; + + if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= b) + return 0; + if (b > 0U) + return 0; + if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (b <= 0U) + return 0; + if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < b) + return 0; + + if (c < 0) + return 0; + if (0 >= c) + return 0; + if (c > 0) + return 0; + if (0 <= c) + return 0; + if (c <= 0) + return 0; + if (0 > c) + return 0; + if (c >= 0) + return 0; + if (0 < c) + return 0; + + // FIXME: These diagnostics are terrible. The issue here is that the signed + // enumeration value was promoted to an unsigned type. + if (c < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + if (0U >= c) + return 0; + if (c > 0U) + return 0; + if (0U <= c) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}} + return 0; + if (c <= 0U) + return 0; + if (0U > c) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}} + return 0; + if (c >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}} + return 0; + if (0U < c) + return 0; + + return 1; +} + +namespace crash_enum_zero_width { +int test() { + enum A : unsigned { + A_foo = 0 + }; + enum A a; + + // used to crash in llvm::APSInt::getMaxValue() + if (a < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}} + return 0; + + return 1; +} +} // namespace crash_enum_zero_width diff --git a/test/Sema/tautological-unsigned-zero-compare.c b/test/Sema/tautological-unsigned-zero-compare.c new file mode 100644 index 000000000000..b9ea02a731a3 --- /dev/null +++ b/test/Sema/tautological-unsigned-zero-compare.c @@ -0,0 +1,257 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-unsigned-zero-compare -verify=silence %s +// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-unsigned-zero-compare -verify=silence -x c++ %s + +unsigned uvalue(void); +signed int svalue(void); + +#define macro(val) val + +#ifdef __cplusplus +template<typename T> +void TFunc() { + // Make sure that we do warn for normal variables in template functions ! + unsigned char c = svalue(); + if (c < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}} + return; + + if (c < macro(0)) + return; + + T v = svalue(); + if (v < 0) + return; +} +#endif + +int main() +{ +#ifdef __cplusplus + TFunc<unsigned char>(); + TFunc<unsigned short>(); +#endif + + unsigned un = uvalue(); + + // silence-no-diagnostics + + if (un == 0) + return 0; + if (un != 0) + return 0; + if (un < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}} + return 0; + if (un <= 0) + return 0; + if (un > 0) + return 0; + if (un >= 0) // expected-warning {{comparison of unsigned expression >= 0 is always true}} + return 0; + + if (0 == un) + return 0; + if (0 != un) + return 0; + if (0 < un) + return 0; + if (0 <= un) // expected-warning {{comparison of 0 <= unsigned expression is always true}} + return 0; + if (0 > un) // expected-warning {{comparison of 0 > unsigned expression is always false}} + return 0; + if (0 >= un) + return 0; + + if (un == 0UL) + return 0; + if (un != 0UL) + return 0; + if (un < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}} + return 0; + if (un <= 0UL) + return 0; + if (un > 0UL) + return 0; + if (un >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}} + return 0; + + if (0UL == un) + return 0; + if (0UL != un) + return 0; + if (0UL < un) + return 0; + if (0UL <= un) // expected-warning {{comparison of 0 <= unsigned expression is always true}} + return 0; + if (0UL > un) // expected-warning {{comparison of 0 > unsigned expression is always false}} + return 0; + if (0UL >= un) + return 0; + + + signed int a = svalue(); + + if (a == 0) + return 0; + if (a != 0) + return 0; + if (a < 0) + return 0; + if (a <= 0) + return 0; + if (a > 0) + return 0; + if (a >= 0) + return 0; + + if (0 == a) + return 0; + if (0 != a) + return 0; + if (0 < a) + return 0; + if (0 <= a) + return 0; + if (0 > a) + return 0; + if (0 >= a) + return 0; + + if (a == 0UL) + return 0; + if (a != 0UL) + return 0; + if (a < 0UL) // expected-warning {{comparison of unsigned expression < 0 is always false}} + return 0; + if (a <= 0UL) + return 0; + if (a > 0UL) + return 0; + if (a >= 0UL) // expected-warning {{comparison of unsigned expression >= 0 is always true}} + return 0; + + if (0UL == a) + return 0; + if (0UL != a) + return 0; + if (0UL < a) + return 0; + if (0UL <= a) // expected-warning {{comparison of 0 <= unsigned expression is always true}} + return 0; + if (0UL > a) // expected-warning {{comparison of 0 > unsigned expression is always false}} + return 0; + if (0UL >= a) + return 0; + + + float fl = 0; + + if (fl == 0) + return 0; + if (fl != 0) + return 0; + if (fl < 0) + return 0; + if (fl <= 0) + return 0; + if (fl > 0) + return 0; + if (fl >= 0) + return 0; + + if (0 == fl) + return 0; + if (0 != fl) + return 0; + if (0 < fl) + return 0; + if (0 <= fl) + return 0; + if (0 > fl) + return 0; + if (0 >= fl) + return 0; + + if (fl == 0UL) + return 0; + if (fl != 0UL) + return 0; + if (fl < 0UL) + return 0; + if (fl <= 0UL) + return 0; + if (fl > 0UL) + return 0; + if (fl >= 0UL) + return 0; + + if (0UL == fl) + return 0; + if (0UL != fl) + return 0; + if (0UL < fl) + return 0; + if (0UL <= fl) + return 0; + if (0UL > fl) + return 0; + if (0UL >= fl) + return 0; + + + double dl = 0; + + if (dl == 0) + return 0; + if (dl != 0) + return 0; + if (dl < 0) + return 0; + if (dl <= 0) + return 0; + if (dl > 0) + return 0; + if (dl >= 0) + return 0; + + if (0 == dl) + return 0; + if (0 != dl) + return 0; + if (0 < dl) + return 0; + if (0 <= dl) + return 0; + if (0 > dl) + return 0; + if (0 >= dl) + return 0; + + if (dl == 0UL) + return 0; + if (dl != 0UL) + return 0; + if (dl < 0UL) + return 0; + if (dl <= 0UL) + return 0; + if (dl > 0UL) + return 0; + if (dl >= 0UL) + return 0; + + if (0UL == dl) + return 0; + if (0UL != dl) + return 0; + if (0UL < dl) + return 0; + if (0UL <= dl) + return 0; + if (0UL > dl) + return 0; + if (0UL >= dl) + return 0; + + return 1; +} diff --git a/test/Sema/tls.c b/test/Sema/tls.c index 6d10363305ff..38bd3f202246 100644 --- a/test/Sema/tls.c +++ b/test/Sema/tls.c @@ -19,8 +19,4 @@ // Haiku does not suppport TLS. // RUN: not %clang_cc1 -triple i586-pc-haiku -fsyntax-only %s -// Bitrig suppports TLS. -// RUN: %clang_cc1 -triple x86_64-pc-bitrig -fsyntax-only %s -// RUN: %clang_cc1 -triple armv6-unknown-bitrig -fsyntax-only %s - __thread int x; diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c index dfbadcfe62c7..048112767480 100644 --- a/test/Sema/transparent-union.c +++ b/test/Sema/transparent-union.c @@ -102,7 +102,7 @@ union pr15134v2 { union pr30520v { void b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'void'}} -union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'int []'}} +union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{flexible array member 'b' in a union is not allowed}} // expected-note@+1 2 {{forward declaration of 'struct stb'}} union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}} diff --git a/test/Sema/types.c b/test/Sema/types.c index 9981be50ad4f..f44057dc4029 100644 --- a/test/Sema/types.c +++ b/test/Sema/types.c @@ -75,7 +75,7 @@ typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vect // no support for vector enum type enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}} -int x4 __attribute__((ext_vector_type(64))); // expected-error {{'ext_vector_type' attribute only applies to types}} +int x4 __attribute__((ext_vector_type(64))); // expected-error {{'ext_vector_type' attribute only applies to typedefs}} // rdar://16492792 typedef __attribute__ ((ext_vector_type(32),__aligned__(32))) unsigned char uchar32; diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c index 58ad8278f201..c574f5e4afee 100644 --- a/test/Sema/unused-expr.c +++ b/test/Sema/unused-expr.c @@ -96,7 +96,7 @@ int t6() { return 0; } -int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to functions}} +int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}} // PR4010 int (*fn4)(void) __attribute__ ((warn_unused_result)); diff --git a/test/Sema/vector_swizzle_length.c b/test/Sema/vector_swizzle_length.c new file mode 100644 index 000000000000..5e6b1e7d67a1 --- /dev/null +++ b/test/Sema/vector_swizzle_length.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x c %s -verify -pedantic -fsyntax-only +// expected-no-diagnostics + +typedef float float8 __attribute__((ext_vector_type(8))); + +void foo() { + float8 f2 = (float8){0, 0, 0, 0, 0, 0, 0, 0}; + (void)f2.s01234; + (void)f2.xyzxy; +} diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index ccf374ccd060..7ffaffc07849 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -1282,3 +1282,25 @@ struct HasMoreFields { }; } + +/*! + * Function pointer typedef with variadic params. + * + * @param a + * works + * + * @param ... + * now should work too. + */ +typedef void (*VariadicFnType)(int a, ...); + +/*! + * Function pointer type alias with variadic params. + * + * @param a + * works + * + * @param ... + * now should work too. + */ +using VariadicFnType2 = void (*)(int a, ...); diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m index 3c1a369c4b14..18ab5bd9e096 100644 --- a/test/Sema/warn-documentation.m +++ b/test/Sema/warn-documentation.m @@ -299,3 +299,14 @@ void (^_Nullable blockPointerVariableThatLeadsNowhere)(); @property void (^blockReturnsNothing)(); @end + +/*! + * Block typedef with variadic params. + * + * @param a + * works + * + * @param ... + * now should work too. + */ +typedef void (^VariadicBlockType)(int a, ...); diff --git a/test/Sema/warn-thread-safety-analysis.c b/test/Sema/warn-thread-safety-analysis.c index 425ce4c196a6..0a375b873e69 100644 --- a/test/Sema/warn-thread-safety-analysis.c +++ b/test/Sema/warn-thread-safety-analysis.c @@ -130,4 +130,4 @@ int main() { // We had a problem where we'd skip all attributes that follow a late-parsed // attribute in a single __attribute__. -void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to fields and global variables}} +void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to non-static data members and global variables}} diff --git a/test/Sema/warn-unreachable-ms.c b/test/Sema/warn-unreachable-ms.c new file mode 100644 index 000000000000..421415e932f0 --- /dev/null +++ b/test/Sema/warn-unreachable-ms.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fsyntax-only -verify -fms-extensions -Wunreachable-code + +void f(); + +void g1() { + __try { + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(1) { + f(); + } + + // Completely empty. + __try { + } __except(1) { + } + + __try { + f(); + return; + } __except(1) { // Filter expression should not be marked as unreachable. + // Empty __except body. + } +} + +void g2() { + __try { + // Nested __try. + __try { + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(2) { + } + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(1) { + f(); + } +} + +void g3() { + __try { + __try { + f(); + } __except (1) { + __leave; // should exit outer try + } + __leave; + f(); // expected-warning{{never be executed}} + } __except (1) { + } +} diff --git a/test/Sema/wchar.c b/test/Sema/wchar.c index 74151edede03..e84fe3e5526b 100644 --- a/test/Sema/wchar.c +++ b/test/Sema/wchar.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -// RUN: %clang_cc1 %s -fsyntax-only -fshort-wchar -verify -DSHORT_WCHAR +// RUN: %clang_cc1 %s -fsyntax-only -fwchar-type=short -fno-signed-wchar -verify -DSHORT_WCHAR typedef __WCHAR_TYPE__ wchar_t; diff --git a/test/Sema/xray-always-instrument-attr.c b/test/Sema/xray-always-instrument-attr.c index 3c063e21a68f..b52369010287 100644 --- a/test/Sema/xray-always-instrument-attr.c +++ b/test/Sema/xray-always-instrument-attr.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11 void foo() __attribute__((xray_always_instrument)); -struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}} +struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}} void bar() __attribute__((xray_always_instrument("not-supported"))); // expected-error {{'xray_always_instrument' attribute takes no arguments}} diff --git a/test/Sema/xray-always-instrument-attr.cpp b/test/Sema/xray-always-instrument-attr.cpp index 8d42837ec6bf..d6a33955cd74 100644 --- a/test/Sema/xray-always-instrument-attr.cpp +++ b/test/Sema/xray-always-instrument-attr.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++ void foo [[clang::xray_always_instrument]] (); -struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}} +struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}} class b { void c [[clang::xray_always_instrument]] (); diff --git a/test/Sema/xray-log-args-oob.c b/test/Sema/xray-log-args-oob.c index a6be0f81cb47..585f5fd172ee 100644 --- a/test/Sema/xray-log-args-oob.c +++ b/test/Sema/xray-log-args-oob.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11 void foo(int) __attribute__((xray_log_args(1))); -struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}} +struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}} void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}} diff --git a/test/Sema/xray-log-args-oob.cpp b/test/Sema/xray-log-args-oob.cpp index 414bce0c334a..82f3be30c6de 100644 --- a/test/Sema/xray-log-args-oob.cpp +++ b/test/Sema/xray-log-args-oob.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++ void foo [[clang::xray_log_args(1)]] (int); -struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}} +struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}} void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}} diff --git a/test/Sema/zero-initializer.c b/test/Sema/zero-initializer.c new file mode 100644 index 000000000000..0ab410d4c6d5 --- /dev/null +++ b/test/Sema/zero-initializer.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -std=c99 -Wmissing-field-initializers -Wmissing-braces -verify %s + +// Tests that using {0} in struct initialization or assignment is supported +struct foo { int x; int y; }; +struct bar { struct foo a; struct foo b; }; +struct A { int a; }; +struct B { struct A a; }; +struct C { struct B b; }; +struct D { struct C c; int n; }; + +int main(void) +{ + struct foo f = { 0 }; // no-warning + struct foo g = { 9 }; // expected-warning {{missing field 'y' initializer}} + struct foo h = { 9, 9 }; // no-warning + struct bar i = { 0 }; // no-warning + struct bar j = { 0, 0 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'b' initializer}} + struct bar k = { { 9, 9 }, { 9, 9 } }; // no-warning + struct bar l = { { 9, 9 }, { 0 } }; // no-warning + struct bar m = { { 0 }, { 0 } }; // no-warning + struct bar n = { { 0 }, { 9, 9 } }; // no-warning + struct bar o = { { 9 }, { 9, 9 } }; // expected-warning {{missing field 'y' initializer}} + struct C p = { 0 }; // no-warning + struct C q = { 9 }; // warning suppressed for struct with single element + struct D r = { 9 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'n' initializer}} + f = (struct foo ) { 0 }; // no-warning + g = (struct foo ) { 9 }; // expected-warning {{missing field 'y' initializer}} + h = (struct foo ) { 9, 9 }; // no-warning + i = (struct bar) { 0 }; // no-warning + j = (struct bar) { 0, 0 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'b' initializer}} + k = (struct bar) { { 9, 9 }, { 9, 9 } }; // no-warning + l = (struct bar) { { 9, 9 }, { 0 } }; // no-warning + m = (struct bar) { { 0 }, { 0 } }; // no-warning + n = (struct bar) { { 0 }, { 9, 9 } }; // no-warning + o = (struct bar) { { 9 }, { 9, 9 } }; // expected-warning {{missing field 'y' initializer}} + p = (struct C) { 0 }; // no-warning + q = (struct C) { 9 }; // warning suppressed for struct with single element + r = (struct D) { 9 }; // expected-warning {{suggest braces around initialization of subobject}} expected-warning {{missing field 'n' initializer}} + + return 0; +} |