diff options
Diffstat (limited to 'test/Frontend')
| -rw-r--r-- | test/Frontend/ast-main.c | 6 | ||||
| -rw-r--r-- | test/Frontend/ast-main.cpp | 6 | ||||
| -rw-r--r-- | test/Frontend/dependency-gen-escaping.c | 2 | ||||
| -rw-r--r-- | test/Frontend/dependency-gen-has-include.c | 40 | ||||
| -rw-r--r-- | test/Frontend/dependency-gen.c | 10 | ||||
| -rw-r--r-- | test/Frontend/fixed_point.c | 399 | ||||
| -rw-r--r-- | test/Frontend/fixed_point_conversions.c | 283 | ||||
| -rw-r--r-- | test/Frontend/fixed_point_declarations.c | 16 | ||||
| -rw-r--r-- | test/Frontend/fixed_point_to_bool.c | 53 | ||||
| -rw-r--r-- | test/Frontend/fixed_point_unknown_conversions.c | 49 | ||||
| -rw-r--r-- | test/Frontend/float16.cpp | 326 | ||||
| -rw-r--r-- | test/Frontend/noderef.c | 209 | ||||
| -rw-r--r-- | test/Frontend/noderef.cpp | 102 | ||||
| -rw-r--r-- | test/Frontend/noderef_on_non_pointers.m | 11 | ||||
| -rw-r--r-- | test/Frontend/noderef_templates.cpp | 15 | ||||
| -rw-r--r-- | test/Frontend/optimization-remark-with-hotness.c | 4 | ||||
| -rw-r--r-- | test/Frontend/plugin-unknown.c | 5 | ||||
| -rw-r--r-- | test/Frontend/warning-stdlibcxx-darwin.cpp | 3 | ||||
| -rw-r--r-- | test/Frontend/windows-exceptions.cpp | 12 |
19 files changed, 804 insertions, 747 deletions
diff --git a/test/Frontend/ast-main.c b/test/Frontend/ast-main.c index 43237a12ef59..74e8bcf6db66 100644 --- a/test/Frontend/ast-main.c +++ b/test/Frontend/ast-main.c @@ -1,6 +1,6 @@ -// RUN: %clang -emit-llvm -S -o %t1.ll -x c - < %s -// RUN: %clang -emit-ast -o %t.ast %s -// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast +// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t1.ll -x c - < %s +// RUN: env SDKROOT="/" %clang -emit-ast -o %t.ast %s +// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast // RUN: diff %t1.ll %t2.ll int main() { diff --git a/test/Frontend/ast-main.cpp b/test/Frontend/ast-main.cpp index 4bddbe1372a0..89fd5e5a6389 100644 --- a/test/Frontend/ast-main.cpp +++ b/test/Frontend/ast-main.cpp @@ -1,6 +1,6 @@ -// RUN: %clang -emit-llvm -S -o %t1.ll -x c++ - < %s -// RUN: %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s -// RUN: %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast +// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t1.ll -x c++ - < %s +// RUN: env SDKROOT="/" %clang -fno-delayed-template-parsing -emit-ast -o %t.ast %s +// RUN: env SDKROOT="/" %clang -emit-llvm -S -o %t2.ll -x ast - < %t.ast // RUN: diff %t1.ll %t2.ll // http://llvm.org/bugs/show_bug.cgi?id=15377 diff --git a/test/Frontend/dependency-gen-escaping.c b/test/Frontend/dependency-gen-escaping.c index c8d1191674c8..deca57e4172c 100644 --- a/test/Frontend/dependency-gen-escaping.c +++ b/test/Frontend/dependency-gen-escaping.c @@ -21,7 +21,7 @@ // Backslash followed by # or space should escape both characters, because // that's what GNU Make wants. GCC does the right thing with space, but not // #, so Clang does too. (There should be 3 backslashes before the #.) -// SEP2F: a\b\\#c\\\ d.h +// SEP2F: a{{[/\\]}}b{{[/\\]}}\#c{{/|\\\\}}\ d.h // With -fms-compatibility, Backslashes in #include are treated as path separators. // Backslashes are given in the emission for special characters, like 0x20 or 0x23. // SEP5C: a{{[/\\]}}b{{[/\\]}}\#c{{/|\\\\}}\ d.h diff --git a/test/Frontend/dependency-gen-has-include.c b/test/Frontend/dependency-gen-has-include.c new file mode 100644 index 000000000000..e8abb2c9c163 --- /dev/null +++ b/test/Frontend/dependency-gen-has-include.c @@ -0,0 +1,40 @@ +// REQUIRES: shell + +// Basic test +// RUN: rm -rf %t.dir +// RUN: mkdir %t.dir +// RUN: mkdir %t.dir/a +// RUN: echo "#ifndef HEADER_A" > %t.dir/a/header.h +// RUN: echo "#define HEADER_A" >> %t.dir/a/header.h +// RUN: echo "#endif" >> %t.dir/a/header.h +// RUN: mkdir %t.dir/system +// RUN: echo "#define SYSTEM_HEADER" > %t.dir/system/system-header.h +// RUN: mkdir %t.dir/next-a +// RUN: echo "#if __has_include_next(<next-header.h>)" > %t.dir/next-a/next-header.h +// RUN: echo "#endif" >> %t.dir/next-a/next-header.h +// RUN: mkdir %t.dir/next-b +// RUN: echo "#define NEXT_HEADER" > %t.dir/next-b/next-header.h + +// RUN: %clang -MD -MF %t.dir/file.deps %s -fsyntax-only -I %t.dir -isystem %t.dir/system -I %t.dir/next-a -I %t.dir/next-b +// RUN: FileCheck -input-file=%t.dir/file.deps %s +// CHECK: dependency-gen-has-include.o +// CHECK: dependency-gen-has-include.c +// CHECK: a/header.h +// CHECK-NOT: missing/file.h +// CHECK: system/system-header.h +// CHECK: next-a/next-header.h +// CHECK: next-b/next-header.h + +// Verify that we ignore system headers in user-only headers mode. +// RUN: %clang -MMD -MF %t.dir/user-headers.deps %s -fsyntax-only -I %t.dir -isystem %t.dir/system -I %t.dir/next-a -I %t.dir/next-b +// RUN: FileCheck -input-file=%t.dir/user-headers.deps --check-prefix CHECK-USER-HEADER %s +// CHECK-USER-HEADER-NOT: system/system-header.h + +#if __has_include("a/header.h") +#endif +#if __has_include("missing/file.h") +#endif +#if __has_include(<system-header.h>) +#endif + +#include <next-header.h> diff --git a/test/Frontend/dependency-gen.c b/test/Frontend/dependency-gen.c index cd222c5dfd9a..963419cb1188 100644 --- a/test/Frontend/dependency-gen.c +++ b/test/Frontend/dependency-gen.c @@ -4,19 +4,19 @@ // RUN: echo > %t.dir/a/b/x.h // RUN: cd %t.dir // RUN: %clang -MD -MF - %s -fsyntax-only -I a/b | FileCheck -check-prefix=CHECK-ONE %s -// CHECK-ONE: {{ }}a/b{{[/\\]}}x.h +// CHECK-ONE: {{ }}a{{[/\\]}}b{{[/\\]}}x.h // PR8974 (-include flag) // RUN: %clang -MD -MF - %s -fsyntax-only -include a/b/x.h -DINCLUDE_FLAG_TEST | FileCheck -check-prefix=CHECK-TWO %s -// CHECK-TWO: {{ }}a/b/x.h +// CHECK-TWO: {{ }}a{{[/\\]}}b{{[/\\]}}x.h // rdar://problem/9734352 (paths involving ".") // RUN: %clang -MD -MF - %s -fsyntax-only -I ./a/b | FileCheck -check-prefix=CHECK-THREE %s -// CHECK-THREE: {{ }}a/b{{[/\\]}}x.h +// CHECK-THREE: {{ }}a{{[/\\]}}b{{[/\\]}}x.h // RUN: %clang -MD -MF - %s -fsyntax-only -I .//./a/b/ | FileCheck -check-prefix=CHECK-FOUR %s -// CHECK-FOUR: {{ }}a/b{{[/\\]}}x.h +// CHECK-FOUR: {{ }}a{{[/\\]}}b{{[/\\]}}x.h // RUN: %clang -MD -MF - %s -fsyntax-only -I a/b/. | FileCheck -check-prefix=CHECK-FIVE %s -// CHECK-FIVE: {{ }}a/b/.{{[/\\]}}x.h +// CHECK-FIVE: {{ }}a{{[/\\]}}b{{[/\\]}}.{{[/\\]}}x.h // RUN: cd a/b // RUN: %clang -MD -MF - %s -fsyntax-only -I ./ | FileCheck -check-prefix=CHECK-SIX %s // CHECK-SIX: {{ }}x.h diff --git a/test/Frontend/fixed_point.c b/test/Frontend/fixed_point.c deleted file mode 100644 index 3a67718fba8e..000000000000 --- a/test/Frontend/fixed_point.c +++ /dev/null @@ -1,399 +0,0 @@ -// RUN: %clang_cc1 -x c -ffixed-point -ast-dump %s | FileCheck %s --strict-whitespace - -/* Various contexts where type _Accum can appear. */ - -// Primary fixed point types -signed short _Accum s_short_accum; -signed _Accum s_accum; -signed long _Accum s_long_accum; -unsigned short _Accum u_short_accum; -unsigned _Accum u_accum; -unsigned long _Accum u_long_accum; -signed short _Fract s_short_fract; -signed _Fract s_fract; -signed long _Fract s_long_fract; -unsigned short _Fract u_short_fract; -unsigned _Fract u_fract; -unsigned long _Fract u_long_fract; - -// Aliased fixed point types -short _Accum short_accum; -_Accum accum; -long _Accum long_accum; -short _Fract short_fract; -_Fract fract; -long _Fract long_fract; - -// Saturated fixed point types -_Sat signed short _Accum sat_s_short_accum; -_Sat signed _Accum sat_s_accum; -_Sat signed long _Accum sat_s_long_accum; -_Sat unsigned short _Accum sat_u_short_accum; -_Sat unsigned _Accum sat_u_accum; -_Sat unsigned long _Accum sat_u_long_accum; -_Sat signed short _Fract sat_s_short_fract; -_Sat signed _Fract sat_s_fract; -_Sat signed long _Fract sat_s_long_fract; -_Sat unsigned short _Fract sat_u_short_fract; -_Sat unsigned _Fract sat_u_fract; -_Sat unsigned long _Fract sat_u_long_fract; - -// Aliased saturated fixed point types -_Sat short _Accum sat_short_accum; -_Sat _Accum sat_accum; -_Sat long _Accum sat_long_accum; -_Sat short _Fract sat_short_fract; -_Sat _Fract sat_fract; -_Sat long _Fract sat_long_fract; - -//CHECK: |-VarDecl {{.*}} s_short_accum 'short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum' -//CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} s_short_fract 'short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} s_fract '_Fract' -//CHECK-NEXT: |-VarDecl {{.*}} s_long_fract 'long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract 'unsigned short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} u_fract 'unsigned _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract 'unsigned long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum' -//CHECK-NEXT: |-VarDecl {{.*}} long_accum 'long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} short_fract 'short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} fract '_Fract' -//CHECK-NEXT: |-VarDecl {{.*}} long_fract 'long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_short_accum '_Sat short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_accum '_Sat _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_long_accum '_Sat long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_short_accum '_Sat unsigned short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_accum '_Sat unsigned _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_long_accum '_Sat unsigned long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_short_fract '_Sat short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_fract '_Sat _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_s_long_fract '_Sat long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_short_fract '_Sat unsigned short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_fract '_Sat unsigned _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_u_long_fract '_Sat unsigned long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_short_accum '_Sat short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_accum '_Sat _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_long_accum '_Sat long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sat_short_fract '_Sat short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_fract '_Sat _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sat_long_fract '_Sat long _Fract' - -#define MIX_TYPE_SPEC(SPEC, SIGN, SIZE, ID) \ - SPEC SIGN SIZE _Accum ID; \ - SIGN SPEC SIZE _Accum ID ## 2; \ - SIGN SIZE SPEC _Accum ID ## 3; \ - SIGN SIZE _Accum SPEC ID ## 4; - -/* Mixing fixed point types with other type specifiers */ - -#define MIX_VOLATILE(SIGN, SIZE, ID) MIX_TYPE_SPEC(volatile, SIGN, SIZE, ID) -#define MIX_ATOMIC(SIGN, SIZE, ID) MIX_TYPE_SPEC(_Atomic, SIGN, SIZE, ID) -#define MIX_CONST(SIGN, SIZE, ID) MIX_TYPE_SPEC(const, SIGN, SIZE, ID) - -MIX_VOLATILE(signed, short, vol_s_short_accum) -MIX_ATOMIC(signed, short, atm_s_short_accum) -MIX_CONST(signed, short, const_s_short_accum) - -// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum 'volatile short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum2 'volatile short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum3 'volatile short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum4 'volatile short _Accum' - -// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum '_Atomic(short _Accum)' -// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum2 '_Atomic(short _Accum)' -// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum3 '_Atomic(short _Accum)' -// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum4 '_Atomic(short _Accum)' - -// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum 'const short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum2 'const short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum3 'const short _Accum' -// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum4 'const short _Accum' - -/* Typedefs */ - -// Primary fixed point types -typedef signed short _Accum SsA_t; -typedef signed _Accum SA_t; -typedef signed long _Accum SlA_t; -typedef unsigned short _Accum UsA_t; -typedef unsigned _Accum UA_t; -typedef unsigned long _Accum UlA_t; -typedef signed short _Fract SsF_t; -typedef signed _Fract SF_t; -typedef signed long _Fract SlF_t; -typedef unsigned short _Fract UsF_t; -typedef unsigned _Fract UF_t; -typedef unsigned long _Fract UlF_t; - -// Aliased fixed point types -typedef short _Accum sA_t; -typedef _Accum A_t; -typedef long _Accum lA_t; -typedef short _Fract sF_t; -typedef _Fract F_t; -typedef long _Fract lF_t; - -// Saturated fixed point types -typedef _Sat signed short _Accum SatSsA_t; -typedef _Sat signed _Accum SatSA_t; -typedef _Sat signed long _Accum SatSlA_t; -typedef _Sat unsigned short _Accum SatUsA_t; -typedef _Sat unsigned _Accum SatUA_t; -typedef _Sat unsigned long _Accum SatUlA_t; -typedef _Sat signed short _Fract SatSsF_t; -typedef _Sat signed _Fract SatSF_t; -typedef _Sat signed long _Fract SatSlF_t; -typedef _Sat unsigned short _Fract SatUsF_t; -typedef _Sat unsigned _Fract SatUF_t; -typedef _Sat unsigned long _Fract SatUlF_t; - -// Aliased saturated fixed point types -typedef _Sat short _Accum SatsA_t; -typedef _Sat _Accum SatA_t; -typedef _Sat long _Accum SatlA_t; -typedef _Sat short _Fract SatsF_t; -typedef _Sat _Fract SatF_t; -typedef _Sat long _Fract SatlF_t; - -SsA_t SsA_type; -SA_t SA_type; -SlA_t SlA_type; -UsA_t UsA_type; -UA_t UA_type; -UlA_t UlA_type; -SsF_t SsF_type; -SF_t SF_type; -SlF_t SlF_type; -UsF_t UsF_type; -UF_t UF_type; -UlF_t UlF_type; - -sA_t sA_type; -A_t A_type; -lA_t lA_type; -sF_t sF_type; -F_t F_type; -lF_t lF_type; - -SatSsA_t SatSsA_type; -SatSA_t SatSA_type; -SatSlA_t SatSlA_type; -SatUsA_t SatUsA_type; -SatUA_t SatUA_type; -SatUlA_t SatUlA_type; -SatSsF_t SatSsF_type; -SatSF_t SatSF_type; -SatSlF_t SatSlF_type; -SatUsF_t SatUsF_type; -SatUF_t SatUF_type; -SatUlF_t SatUlF_type; - -SatsA_t SatsA_type; -SatA_t SatA_type; -SatlA_t SatlA_type; -SatsF_t SatsF_type; -SatF_t SatF_type; -SatlF_t SatlF_type; - -//CHECK: |-VarDecl {{.*}} SsA_type 'SsA_t':'short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SA_type 'SA_t':'_Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SlA_type 'SlA_t':'long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} UsA_type 'UsA_t':'unsigned short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} UA_type 'UA_t':'unsigned _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} UlA_type 'UlA_t':'unsigned long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SsF_type 'SsF_t':'short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SF_type 'SF_t':'_Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SlF_type 'SlF_t':'long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} UsF_type 'UsF_t':'unsigned short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} UF_type 'UF_t':'unsigned _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} UlF_type 'UlF_t':'unsigned long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} sA_type 'sA_t':'short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} A_type 'A_t':'_Accum' -//CHECK-NEXT: |-VarDecl {{.*}} lA_type 'lA_t':'long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} sF_type 'sF_t':'short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} F_type 'F_t':'_Fract' -//CHECK-NEXT: |-VarDecl {{.*}} lF_type 'lF_t':'long _Fract' - -//CHECK-NEXT: |-VarDecl {{.*}} SatSsA_type 'SatSsA_t':'_Sat short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatSA_type 'SatSA_t':'_Sat _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatSlA_type 'SatSlA_t':'_Sat long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatUsA_type 'SatUsA_t':'_Sat unsigned short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatUA_type 'SatUA_t':'_Sat unsigned _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatUlA_type 'SatUlA_t':'_Sat unsigned long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatSsF_type 'SatSsF_t':'_Sat short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatSF_type 'SatSF_t':'_Sat _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatSlF_type 'SatSlF_t':'_Sat long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatUsF_type 'SatUsF_t':'_Sat unsigned short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatUF_type 'SatUF_t':'_Sat unsigned _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatUlF_type 'SatUlF_t':'_Sat unsigned long _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatsA_type 'SatsA_t':'_Sat short _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatA_type 'SatA_t':'_Sat _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatlA_type 'SatlA_t':'_Sat long _Accum' -//CHECK-NEXT: |-VarDecl {{.*}} SatsF_type 'SatsF_t':'_Sat short _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatF_type 'SatF_t':'_Sat _Fract' -//CHECK-NEXT: |-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract' - -// Fixed point literal exponent syntax -_Accum decexp1 = 1.575e1k; -_Accum decexp2 = 1.575E1k; -_Accum decexp3 = 1575e-2k; -_Accum decexp4 = 1575E-2k; - -_Accum hexexp1 = 0x0.3p10k; -_Accum hexexp2 = 0x0.3P10k; -_Accum hexexp3 = 0x30000p-10k; -_Accum hexexp4 = 0x30000P-10k; - -_Accum zeroexp1 = 1e0k; -_Accum zeroexp2 = 1e-0k; - -//CHECK-NEXT: |-VarDecl {{.*}} decexp1 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 -//CHECK-NEXT: |-VarDecl {{.*}} decexp2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 -//CHECK-NEXT: |-VarDecl {{.*}} decexp3 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 -//CHECK-NEXT: |-VarDecl {{.*}} decexp4 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 - -//CHECK-NEXT: |-VarDecl {{.*}} hexexp1 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 -//CHECK-NEXT: |-VarDecl {{.*}} hexexp2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 -//CHECK-NEXT: |-VarDecl {{.*}} hexexp3 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 -//CHECK-NEXT: |-VarDecl {{.*}} hexexp4 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 - -//CHECK-NEXT: |-VarDecl {{.*}} zeroexp1 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 -//CHECK-NEXT: |-VarDecl {{.*}} zeroexp2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 - -// Fixed point literal values -_Accum literal1 = 2.5k; // Precise decimal -_Accum literal2 = 0.0k; // Zero -_Accum literal3 = 1.1k; // Imprecise decimal -_Accum literal4 = 1.11k; -_Accum literal5 = 1.111k; -_Accum literal6 = 1.1111k; -_Accum literal7 = 1.11111k; // After some point after the radix, adding any more - // digits to the literal will not result in any - // further precision since the nth digit added may - // be less than the precision that can be - // represented by the fractional bits of the type. - // This results in the same value being stored for - // the type. - -//CHECK-NEXT: |-VarDecl {{.*}} literal1 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5 -//CHECK-NEXT: |-VarDecl {{.*}} literal2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0 -//CHECK-NEXT: |-VarDecl {{.*}} literal3 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0999755859375 -//CHECK-NEXT: |-VarDecl {{.*}} literal4 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.1099853515625 -//CHECK-NEXT: |-VarDecl {{.*}} literal5 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.110992431640625 -//CHECK-NEXT: |-VarDecl {{.*}} literal6 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375 -//CHECK-NEXT: |-VarDecl {{.*}} literal7 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375 - -long _Accum longaccumliteral = 0.99999999lk; -long _Accum longaccumliteral2 = 0.999999999lk; -long _Accum verylongaccumliteral = 0.99999999999999999999999999lk; -long _Fract longfractliteral = 0.99999999lr; -long _Fract longfractliteral2 = 0.999999999lr; -long _Fract verylongfractliteral = 0.99999999999999999999999999lr; - -//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.999999989755451679229736328125 -//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral2 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999986030161380767822265625 -//CHECK-NEXT: |-VarDecl {{.*}} verylongaccumliteral 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875 -//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral 'long _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.999999989755451679229736328125 -//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral2 'long _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999986030161380767822265625 -//CHECK-NEXT: |-VarDecl {{.*}} verylongfractliteral 'long _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875 - -unsigned _Accum uliteral1 = 2.5uk; // Unsigned -_Accum literal8 = -2.5k; // Negative - -//CHECK-NEXT: |-VarDecl {{.*}} uliteral1 'unsigned _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Accum' 2.5 -//CHECK-NEXT: |-VarDecl {{.*}} literal8 '_Accum' cinit -//CHECK-NEXT: `-UnaryOperator {{.*}} '_Accum' prefix '-' -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5 - -short _Accum literalexact1 = 0.9921875hk; // Exact value -_Accum literalexact2 = 0.999969482421875k; - -//CHECK-NEXT: |-VarDecl {{.*}} literalexact1 'short _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.9921875 -//CHECK-NEXT: |-VarDecl {{.*}} literalexact2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.999969482421875 - -// Unfortunately we do not have enough space to store the exact decimal value of -// 0.9999999995343387126922607421875 ((1 << 31) - 1), but we can still use a -// large number of 9s to get the max fractional value. -long _Accum long_accum_max = 0.999999999999999999999999999lk; - -//CHECK-NEXT: |-VarDecl {{.*}} long_accum_max 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875 - -// Epsilon -short _Accum short_accum_eps = 0.0078125hk; -short _Accum short_accum_eps2 = 0.0078124hk; // Less than epsilon floors to zero -_Accum accum_eps = 0.000030517578125k; -_Accum accum_eps2 = 0.000030517578124k; -long _Accum long_accum_eps = 0x1p-31lk; -long _Accum long_accum_eps2 = 0x0.99999999p-31lk; - -//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps 'short _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0078125 -//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps2 'short _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0 -//CHECK-NEXT: |-VarDecl {{.*}} accum_eps '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.000030517578125 -//CHECK-NEXT: |-VarDecl {{.*}} accum_eps2 '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0 -//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0000000004656612873077392578125 -//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps2 'long _Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0 - -// Fract literals can be one but evaluate to the respective Fract max -short _Fract short_fract_one = 1.0hr; -_Fract fract_one = 1.0r; -long _Fract long_fract_one = 1.0lr; -unsigned short _Fract u_short_fract_one = 1.0uhr; -unsigned _Fract u_fract_one = 1.0ur; -unsigned long _Fract u_long_fract_one = 1.0ulr; - -//CHECK-NEXT: |-VarDecl {{.*}} short_fract_one 'short _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Fract' 0.9921875 -//CHECK-NEXT: |-VarDecl {{.*}} fract_one '_Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Fract' 0.999969482421875 -//CHECK-NEXT: |-VarDecl {{.*}} long_fract_one 'long _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875 - -//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract_one 'unsigned short _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned short _Fract' 0.99609375 -//CHECK-NEXT: |-VarDecl {{.*}} u_fract_one 'unsigned _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Fract' 0.9999847412109375 -//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract_one 'unsigned long _Fract' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned long _Fract' 0.99999999976716935634613037109375 - -_Accum literallast = 1.0k; // One - -//CHECK-NEXT: `-VarDecl {{.*}} literallast '_Accum' cinit -//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 diff --git a/test/Frontend/fixed_point_conversions.c b/test/Frontend/fixed_point_conversions.c new file mode 100644 index 000000000000..7e98fb1e130c --- /dev/null +++ b/test/Frontend/fixed_point_conversions.c @@ -0,0 +1,283 @@ +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s -check-prefix=DEFAULT +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s -check-prefix=SAME + +void TestFixedPointCastSameType() { + _Accum a = 2.5k; + _Accum a2 = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4 + + a2 = (_Accum)a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4 +} + +void TestFixedPointCastDown() { + long _Accum la = 2.5lk; + _Accum a = la; + // DEFAULT: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8 + // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + a = (_Accum)la; + // DEFAULT: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8 + // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + short _Accum sa = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8 + // DEFAULT-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16 + // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2 + + sa = (short _Accum)a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8 + // DEFAULT-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16 + // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2 +} + +void TestFixedPointCastUp() { + short _Accum sa = 2.5hk; + _Accum a = sa; + // DEFAULT: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2 + // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + long _Accum la = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64 + // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16 + // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %la, align 8 + + a = (_Accum)sa; + // DEFAULT: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2 + // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + la = (long _Accum)a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64 + // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16 + // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %la, align 8 +} + +void TestFixedPointCastSignedness() { + _Accum a = 2.5k; + unsigned _Accum ua = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1 + // DEFAULT-NEXT: store i32 [[UACCUM]], i32* %ua, align 4 + // SAME: TestFixedPointCastSignedness + // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // SAME-NEXT: store i32 [[ACCUM]], i32* %ua, align 4 + + a = ua; + // DEFAULT: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // SAME-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + ua = (unsigned _Accum)a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1 + // DEFAULT-NEXT: store i32 [[UACCUM]], i32* %ua, align 4 + + a = (_Accum)ua; + // DEFAULT: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + _Accum a2; + unsigned long _Accum ula = a2; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4 + // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64 + // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 17 + // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %ula, align 8 + // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4 + // SAME-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64 + // SAME-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 16 + // SAME-NEXT: store i64 [[LACCUM]], i64* %ula, align 8 +} + +void TestFixedPointCastSaturation() { + _Accum a; + _Sat short _Accum sat_sa; + _Sat _Accum sat_a; + _Sat long _Accum sat_la; + _Sat unsigned short _Accum sat_usa; + _Sat unsigned _Accum sat_ua; + _Sat unsigned long _Accum sat_ula; + _Sat short _Fract sat_sf; + _Sat _Fract sat_f; + _Sat long _Fract sat_lf; + + // Casting down between types + sat_sa = sat_a; + // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8 + // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]] + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16 + // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_sa, align 2 + + // Accum to Fract, decreasing scale + sat_sf = sat_a; + // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8 + // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[FRACT]], 127 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 127, i32 [[FRACT]] + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -128 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -128, i32 [[RESULT]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i8 + // DEFAULT-NEXT: store i8 [[RESULT_TRUNC]], i8* %sat_sf, align 1 + + // Accum to Fract, same scale + sat_f = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]] + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16 + // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_f, align 2 + + // Accum to Fract, increasing scale + sat_lf = sat_a; + // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i48 + // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = shl i48 [[ACCUM]], 16 + // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i48 [[FRACT]], 2147483647 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i48 2147483647, i48 [[FRACT]] + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i48 [[RESULT]], -2147483648 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i48 -2147483648, i48 [[RESULT]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i48 [[RESULT2]] to i32 + // DEFAULT-NEXT: store i32 [[RESULT_TRUNC]], i32* %sat_lf, align 4 + + // Signed to unsigned, decreasing scale + _Sat _Accum sat_a2; + sat_usa = sat_a2; + // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 7 + // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 65535 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 65535, i32 [[ACCUM]] + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16 + // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2 + // SAME: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4 + // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8 + // SAME-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767 + // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]] + // SAME-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0 + // SAME-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]] + // SAME-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16 + // SAME-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2 + + // Signed to unsigned, increasing scale + sat_ua = sat_a; + // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i33 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i33 [[ACCUM_EXT]], 1 + // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i33 [[ACCUM]], 0 + // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i33 0, i33 [[ACCUM]] + // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i33 [[RESULT2]] to i32 + // DEFAULT-NEXT: store i32 [[RESULT_TRUNC]], i32* %sat_ua, align 4 + // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // SAME-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0 + // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[ACCUM]] + // SAME-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4 + + // Nothing when saturating to the same type and size + sat_a = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %sat_a, align 4 + + // Nothing when assigning back + a = sat_a; + // DEFAULT: [[SAT_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4 + // DEFAULT-NEXT: store i32 [[SAT_ACCUM]], i32* %a, align 4 + + // No overflow when casting from fract to signed accum + sat_a = sat_f; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %sat_f, align 2 + // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32 + // DEFAULT-NEXT: store i32 [[FRACT_EXT]], i32* %sat_a, align 4 + + // Only get overflow checking if signed fract to unsigned accum + sat_ua = sat_sf; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1 + // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i17 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i17 [[FRACT_EXT]], 9 + // DEFAULT-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i17 [[ACCUM]], 0 + // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i17 0, i17 [[ACCUM]] + // DEFAULT-NEXT: [[RESULT_EXT:%[0-9a-z]+]] = sext i17 [[RESULT]] to i32 + // DEFAULT-NEXT: store i32 [[RESULT_EXT]], i32* %sat_ua, align 4 + // SAME: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1 + // SAME-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i16 + // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i16 [[FRACT_EXT]], 8 + // SAME-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i16 [[ACCUM]], 0 + // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i16 0, i16 [[ACCUM]] + // SAME-NEXT: [[RESULT_EXT:%[0-9a-z]+]] = sext i16 [[RESULT]] to i32 + // SAME-NEXT: store i32 [[RESULT_EXT]], i32* %sat_ua, align 4 +} + +void TestFixedPointCastBetFractAccum() { + short _Accum sa; + _Accum a; + long _Accum la; + short _Fract sf; + _Fract f; + long _Fract lf; + unsigned _Accum ua; + unsigned _Fract uf; + + // To lower scale + sf = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8 + // DEFAULT-NEXT: [[FRACT_TRUNC:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i8 + // DEFAULT-NEXT: store i8 [[FRACT_TRUNC]], i8* %sf, align 1 + + // To higher scale + a = sf; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sf, align 1 + // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + // To same scale + f = a; + // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = trunc i32 [[ACCUM]] to i16 + // DEFAULT-NEXT: store i16 [[FRACT]], i16* %f, align 2 + + a = f; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %f, align 2 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4 + + // To unsigned + ua = uf; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32 + // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %ua, align 4 + // SAME: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2 + // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32 + // SAME-NEXT: store i32 [[ACCUM]], i32* %ua, align 4 + + uf = ua; + // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16 + // DEFAULT-NEXT: store i16 [[ACCUM]], i16* %uf, align 2 + // SAME: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16 + // SAME-NEXT: store i16 [[ACCUM]], i16* %uf, align 2 +} diff --git a/test/Frontend/fixed_point_declarations.c b/test/Frontend/fixed_point_declarations.c index 5df54f38d7f6..04ed25d227ca 100644 --- a/test/Frontend/fixed_point_declarations.c +++ b/test/Frontend/fixed_point_declarations.c @@ -1,5 +1,4 @@ // RUN: %clang -ffixed-point -S -emit-llvm %s -o - --target=x86_64-linux | FileCheck %s -// RUN: %clang -ffixed-point -S -emit-llvm %s -o - --target=x86_64-scei-ps4-ubuntu-fast | FileCheck %s // Primary fixed point types signed short _Accum s_short_accum; // CHECK-DAG: @s_short_accum = {{.*}}global i16 0, align 2 @@ -111,3 +110,18 @@ long _Fract long_fract_eps = 0x1p-31lr; // CHECK-DAG: @long_ unsigned short _Fract u_short_fract_eps = 0x1p-8uhr; // CHECK-DAG: @u_short_fract_eps = {{.*}}global i8 1, align 1 unsigned _Fract u_fract_eps = 0x1p-16ur; // CHECK-DAG: @u_fract_eps = {{.*}}global i16 1, align 2 unsigned long _Fract u_long_fract_eps = 0x1p-32ulr; // CHECK-DAG: @u_long_fract_eps = {{.*}}global i32 1, align 4 + +// Zero +short _Accum short_accum_zero = 0.0hk; // CHECK-DAG: @short_accum_zero = {{.*}}global i16 0, align 2 + _Accum accum_zero = 0.0k; // CHECK-DAG: @accum_zero = {{.*}}global i32 0, align 4 +long _Accum long_accum_zero = 0.0lk; // CHECK-DAG: @long_accum_zero = {{.*}}global i64 0, align 8 +unsigned short _Accum u_short_accum_zero = 0.0uhk; // CHECK-DAG: @u_short_accum_zero = {{.*}}global i16 0, align 2 +unsigned _Accum u_accum_zero = 0.0uk; // CHECK-DAG: @u_accum_zero = {{.*}}global i32 0, align 4 +unsigned long _Accum u_long_accum_zero = 0.0ulk; // CHECK-DAG: @u_long_accum_zero = {{.*}}global i64 0, align 8 + +short _Fract short_fract_zero = 0.0hr; // CHECK-DAG: @short_fract_zero = {{.*}}global i8 0, align 1 + _Fract fract_zero = 0.0r; // CHECK-DAG: @fract_zero = {{.*}}global i16 0, align 2 +long _Fract long_fract_zero = 0.0lr; // CHECK-DAG: @long_fract_zero = {{.*}}global i32 0, align 4 +unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 +unsigned _Fract u_fract_zero = 0.0ur; // CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 +unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero = {{.*}}global i32 0, align 4 diff --git a/test/Frontend/fixed_point_to_bool.c b/test/Frontend/fixed_point_to_bool.c new file mode 100644 index 000000000000..13b39b8e7ac4 --- /dev/null +++ b/test/Frontend/fixed_point_to_bool.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s + +_Bool global_b = 1.0k; // @global_b = {{*.}}global i8 1, align 1 +_Bool global_b2 = 0.0k; // @global_b2 = {{*.}}global i8 0, align 1 + +void func() { + _Accum a = 0.5k; + unsigned _Accum ua = 0.5uk; + _Bool b; + + // CHECK: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + // CHECK: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + b = 0.5k; + b = 0.0k; + b = 0.5uk; + b = 0.0uk; + + // CHECK-NEXT: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + // CHECK-NEXT: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + b = (_Bool)0.5r; + b = (_Bool)0.0r; + b = (_Bool)0.5ur; + b = (_Bool)0.0ur; + + // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9a-z]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: [[FROMBOOL:%[0-9a-z]+]] = zext i1 [[NOTZERO]] to i8 + // CHECK-NEXT: store i8 [[FROMBOOL]], i8* %b, align 1 + b = a; + + // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9a-z]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: [[FROMBOOL:%[0-9a-z]+]] = zext i1 [[NOTZERO]] to i8 + // CHECK-NEXT: store i8 [[FROMBOOL]], i8* %b, align 1 + b = ua; + + // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9a-z]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: br i1 [[NOTZERO]], label %if.then, label %if.end + if (a) { + } + + // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9a-z]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: br i1 [[NOTZERO]], label %if.then{{[0-9]+}}, label %if.end{{[0-9]+}} + if (ua) { + } +} diff --git a/test/Frontend/fixed_point_unknown_conversions.c b/test/Frontend/fixed_point_unknown_conversions.c new file mode 100644 index 000000000000..0cd3d046ca0d --- /dev/null +++ b/test/Frontend/fixed_point_unknown_conversions.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -verify -ffixed-point %s + +void func() { + _Bool b; + char c; + int i; + float f; + double d; + double _Complex dc; + int _Complex ic; + struct S { + int i; + } s; + enum E { + A + } e; + int *ptr; + typedef int int_t; + int_t i2; + + _Accum accum; + _Fract fract = accum; // ok + _Accum *accum_ptr; + + accum = b; // expected-error{{conversion between fixed point and '_Bool' is not yet supported}} + accum = i; // expected-error{{conversion between fixed point and 'int' is not yet supported}} + accum = i; // expected-error{{conversion between fixed point and 'int' is not yet supported}} + accum = f; // expected-error{{conversion between fixed point and 'float' is not yet supported}} + accum = d; // expected-error{{conversion between fixed point and 'double' is not yet supported}} + accum = dc; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}} + accum = ic; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}} + accum = s; // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}} + accum = e; // expected-error{{conversion between fixed point and 'enum E' is not yet supported}} + accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}} + accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}} + accum = i2; // expected-error{{conversion between fixed point and 'int_t' (aka 'int') is not yet supported}} + + c = accum; // expected-error{{conversion between fixed point and 'char' is not yet supported}} + i = accum; // expected-error{{conversion between fixed point and 'int' is not yet supported}} + f = accum; // expected-error{{conversion between fixed point and 'float' is not yet supported}} + d = accum; // expected-error{{conversion between fixed point and 'double' is not yet supported}} + dc = accum; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}} + ic = accum; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}} + s = accum; // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}} + e = accum; // expected-error{{conversion between fixed point and 'enum E' is not yet supported}} + ptr = accum; // expected-error{{assigning to 'int *' from incompatible type '_Accum'}} + ptr = accum_ptr; // expected-warning{{incompatible pointer types assigning to 'int *' from '_Accum *'}} + i2 = accum; // expected-error{{conversion between fixed point and 'int' is not yet supported}} +} diff --git a/test/Frontend/float16.cpp b/test/Frontend/float16.cpp deleted file mode 100644 index fa00eae75360..000000000000 --- a/test/Frontend/float16.cpp +++ /dev/null @@ -1,326 +0,0 @@ -// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace -// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace - -/* Various contexts where type _Float16 can appear. */ - -/* Namespace */ -namespace { - _Float16 f1n; - _Float16 f2n = 33.f16; - _Float16 arr1n[10]; - _Float16 arr2n[] = { 1.2, 3.0, 3.e4 }; - const volatile _Float16 func1n(const _Float16 &arg) { - return arg + f2n + arr1n[4] - arr2n[1]; - } -} - -//CHECK: |-NamespaceDecl -//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16' -//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01 -//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]' -//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit -//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]' -//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00 -//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00 -//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04 -//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)' - -/* File */ -_Float16 f1f; -_Float16 f2f = 32.4; -_Float16 arr1f[10]; -_Float16 arr2f[] = { -1.2, -3.0, -3.e4 }; -_Float16 func1f(_Float16 arg); - -//CHECK: |-VarDecl {{.*}} f1f '_Float16' -//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01 -//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]' -//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit -//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]' -//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-' -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00 -//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-' -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00 -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04 -//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)' -//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16' - - -// Mixing __fp16 and Float16 types: -// The _Float16 type is first converted to __fp16 type and then the operation -// is completed as if both operands were of __fp16 type. - -__fp16 B = -0.1; -auto C = -1.0f16 + B; - -// When we do *not* have native half types, we expect __fp16 to be promoted to -// float, and consequently also _Float16 promotions to float: - -//CHECK: -VarDecl {{.*}} used B '__fp16' cinit -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> -//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01 -//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit -//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+' -//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast> -//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast> -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue> -//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16' - -// When do have native half types, we expect to see promotions to fp16: - -//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit -//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> -//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-' -//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01 -//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit -//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+' -//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> -//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 -//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue> -//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16' - - -/* Class */ - -class C1 { - _Float16 f1c; - static const _Float16 f2c; - volatile _Float16 f3c; -public: - C1(_Float16 arg) : f1c(arg), f3c(arg) { } - _Float16 func1c(_Float16 arg ) { - return f1c + arg; - } - static _Float16 func2c(_Float16 arg) { - return arg * C1::f2c; - } -}; - -//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition -//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1 -//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16' -//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static -//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16' -//CHECK-NEXT: | |-AccessSpecDecl -//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16) -//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' -//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16' -//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' -//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16' -//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' -//CHECK-NEXT: | | `-CompoundStmt -//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16) -//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' -//CHECK-NEXT: | | `-CompoundStmt -//CHECK-NEXT: | | `-ReturnStmt -//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}} -//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'C1 *' this -//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' -//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static -//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' -//CHECK-NEXT: | | `-CompoundStmt -//CHECK-NEXT: | | `-ReturnStmt -//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*' -//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' -//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16' - - -/* Template */ - -template <class C> C func1t(C arg) { - return arg * 2.f16; -} - -//CHECK: |-FunctionTemplateDecl {{.*}} func1t -//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C -//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)' -//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C' -//CHECK-NEXT: | | `-CompoundStmt -//CHECK-NEXT: | | `-ReturnStmt -//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*' -//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C' -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00 -//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)' -//CHECK-NEXT: | |-TemplateArgument type '_Float16' -//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16' -//CHECK-NEXT: | `-CompoundStmt -//CHECK-NEXT: | `-ReturnStmt -//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*' -//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue> -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00 - - -template <class C> struct S1 { - C mem1; -}; - -//CHECK: |-ClassTemplateDecl {{.*}} S1 -//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C -//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition -//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1 -//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C' -//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1' - -template <> struct S1<_Float16> { - _Float16 mem2; -}; - - -/* Local */ - -extern int printf (const char *__restrict __format, ...); - -int main(void) { - _Float16 f1l = 1e3f16; -//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03 - - _Float16 f2l = -0.f16; -//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit -//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00 - - _Float16 f3l = 1.000976562; -//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00 - - C1 c1(f1l); -//CHECK: | `-VarDecl{{.*}} used c1 'C1' callinit -//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'C1' 'void (_Float16) -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16' - - S1<_Float16> s1 = { 132.f16 }; -//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'S1<_Float16>' cinit -//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'S1<_Float16>' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02 - - _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) + - func1t(f1l) + s1.mem2 - f1n + f2n; -//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit -//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-' -//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+' -//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16' -//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay> -//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)' -//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp> -//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' -//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16' -//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> -//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)' -//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16' -//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16' -//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}} -//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1' -//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16' -//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16' -//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> -//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}} -//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1' -//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' -//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16' -//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> -//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t') -//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' -//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}} -//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'S1<_Float16>' -//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16' -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' - - auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l); -//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit -//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 -//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit -//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&' -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16' -//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit -//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16' -//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> -//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t') -//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16' - - _Float16 f8l = f4l++; -//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit -//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++' -//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16' - - _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 }; -//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit -//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]' -//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 -//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00 -//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-' -//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01 - - float cvtf = f2n; -//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast> -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' - - double cvtd = f2n; -//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast> -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' - - long double cvtld = f2n; -//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast> -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> -//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' - - _Float16 f2h = 42.0f; -//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01 - - _Float16 d2h = 42.0; -//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01 - - _Float16 ld2h = 42.0l; -//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit -//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> -//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01 -} diff --git a/test/Frontend/noderef.c b/test/Frontend/noderef.c new file mode 100644 index 000000000000..b072b995fcf6 --- /dev/null +++ b/test/Frontend/noderef.c @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -Wno-unused-value -verify %s + +#define NODEREF __attribute__((noderef)) + +struct S { + int a; + int b; +}; + +struct S2 { + int a[2]; + int NODEREF a2[2]; + int *b; + int NODEREF *b2; + struct S *s; + struct S NODEREF *s2; +}; + +int NODEREF *func(int NODEREF *arg) { // expected-note{{arg declared here}} + int y = *arg; // expected-warning{{dereferencing arg; was declared with a 'noderef' type}} + return arg; +} + +void func2(int x) {} + +int test() { + int NODEREF *p; // expected-note 34 {{p declared here}} + int *p2; + + int x = *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + x = *((int NODEREF *)p2); // expected-warning{{dereferencing expression marked as 'noderef'}} + + int NODEREF **q; + int *NODEREF *q2; // expected-note 4 {{q2 declared here}} + + // Indirection + x = **q; // expected-warning{{dereferencing expression marked as 'noderef'}} + p2 = *q2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}} + + **q; // expected-warning{{dereferencing expression marked as 'noderef'}} + + p = *&*q; + p = **&q; + q = &**&q; + p = &*p; + p = *&p; + p = &(*p); + p = *(&p); + x = **&p; // expected-warning{{dereferencing expression marked as 'noderef'}} + + *p = 2; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + *q = p; // ok + **q = 2; // expected-warning{{dereferencing expression marked as 'noderef'}} + *q2 = p2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}} + + p = p + 1; + p = &*(p + 1); + + // Struct member access + struct S NODEREF *s; // expected-note 2 {{s declared here}} + x = s->a; // expected-warning{{dereferencing s; was declared with a 'noderef' type}} + x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}} + p = &s->a; + p = &(*s).b; + + // Nested struct access + struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}} + p = s2_noderef->a; // ok since result is an array in a struct + p = s2_noderef->a2; // ok + p = s2_noderef->b; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}} + p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}} + s = s2_noderef->s; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}} + s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}} + p = s2_noderef->a + 1; + + struct S2 *s2; + p = s2->a; + p = s2->a2; + p = s2->b; + p = s2->b2; + s = s2->s; + s = s2->s2; + &(*(*s2).s2).b; + + // Subscript access + x = p[1]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}} + p2 = q2[0]; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}} + p = q[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + x = p[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + + int NODEREF arr[10]; // expected-note 1 {{arr declared here}} + x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}} + + int NODEREF *(arr2[10]); + int NODEREF *elem = *arr2; + + int NODEREF(*arr3)[10]; + elem = *arr3; + + // Combinations between indirection, subscript, and member access + struct S2 NODEREF *s2_arr[10]; + struct S2 NODEREF *s2_arr2[10][10]; + + p = s2_arr[1]->a; + p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}} + int **bptr = &s2_arr[1]->b; + + x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}} + x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}} + p = &s2_noderef->a[1]; + + // Casting to dereferenceable pointer + p2 = p; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + p2 = *q; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + p2 = q[0]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + s2 = s2_arr[1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + p2 = p, p2 = *q; // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}} + + // typedefs + typedef int NODEREF *ptr_t; + ptr_t ptr; // expected-note 2 {{ptr declared here}} + ptr_t *ptr2; + *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}} + *ptr2; + **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}} + + typedef struct S2 NODEREF *s2_ptr_t; + s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}} + s2_ptr->a; // ok since result is an array in a struct + s2_ptr->a2; // ok + s2_ptr->b; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}} + s2_ptr->b2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}} + s2_ptr->s; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}} + s2_ptr->s2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}} + s2_ptr->a + 1; + + typedef int(int_t); + typedef int_t NODEREF *(noderef_int_t); + typedef noderef_int_t *noderef_int_nested_t; + noderef_int_nested_t noderef_int_nested_ptr; + *noderef_int_nested_ptr; + **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}} + + typedef int_t *(NODEREF noderef_int2_t); + typedef noderef_int2_t *noderef_int2_nested_t; + noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}} + *noderef_int2_nested_ptr; // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}} + + typedef int_t *(noderef_int3_t); + typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t))); + noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}} + *noderef_int3_nested_ptr; // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}} + + // Parentheses + (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}} + + (p[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + (q[0]); // ok + (q[0][0]); // expected-warning{{dereferencing expression marked as 'noderef'}} + (q2[0]); // expected-warning{{dereferencing q2; was declared with a 'noderef' type}} + (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + + (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}} + (*(ptr2)); + (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}} + + // Functions + x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}} + + // Casting is ok + q = (int NODEREF **)&p; + q = (int NODEREF **)&p2; + q = &p; + q = &p2; + x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}} + + // Other expressions + func2(*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + func2(*p + 1); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + func2(!*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + func2((x = *p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + + // Other statements + if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + else if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + switch (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + for (*p; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}} + for (*p; *p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + for (*p;; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + for (; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}} + for (*p;;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + for (;*p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + for (;;*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + while (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + do {} while (*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}} + return *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}} +} diff --git a/test/Frontend/noderef.cpp b/test/Frontend/noderef.cpp new file mode 100644 index 000000000000..15eb4e457c20 --- /dev/null +++ b/test/Frontend/noderef.cpp @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 -fblocks -verify %s + +/** + * Test 'noderef' attribute with c++ constructs. + */ + +#define NODEREF __attribute__((noderef)) + +void Normal() { + int NODEREF i; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int NODEREF *i_ptr; // expected-note 2 {{i_ptr declared here}} + int NODEREF **i_ptr2; // ok + int *NODEREF i_ptr3; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int *NODEREF *i_ptr4; // ok + + auto NODEREF *auto_i_ptr = i_ptr; + auto NODEREF auto_i = i; // expected-warning{{'noderef' can only be used on an array or pointer type}} + + struct { + int x; + int y; + } NODEREF *s; + + int __attribute__((noderef(10))) * no_args; // expected-error{{'noderef' attribute takes no arguments}} + + int i2 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} + int &i3 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} + int *i_ptr5 = i_ptr; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + int *i_ptr6(i_ptr); // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} +} + +const int NODEREF *const_i_ptr; +static int NODEREF *static_i_ptr; + +void ParenTypes() { + int NODEREF(*i_ptr); // ok (same as `int NODEREF *`) + int NODEREF *(*i_ptr2); // ok (same as `int NODEREF **`) +} + +// Function declarations +int NODEREF func(); // expected-warning{{'noderef' can only be used on an array or pointer type}} +int NODEREF *func2(); // ok (returning pointer) + +typedef int NODEREF (*func3)(int); // expected-warning{{'noderef' can only be used on an array or pointer type}} +typedef int NODEREF *(*func4)(int); + +void Arrays() { + int NODEREF i_arr[10]; // ok + int NODEREF i_arr2[10][10]; // ok + int NODEREF *i_arr3[10]; // ok + int NODEREF i_arr4[] = {1, 2}; +} + +void ParenArrays() { + int NODEREF(i_ptr[10]); + int NODEREF(i_ptr2[10])[10]; +} + +typedef int NODEREF *(*func5[10])(int); + +// Arguments +void func6(int NODEREF x); // expected-warning{{'noderef' can only be used on an array or pointer type}} +void func7(int NODEREF *x); +void func8() NODEREF; + +void References() { + int x = 2; + int NODEREF &y = x; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int *xp = &x; + int NODEREF *&a = xp; // ok (reference to a NODEREF *) + int *NODEREF &b = xp; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +void BlockPointers() { + typedef int NODEREF (^IntBlock)(); // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +class A { +public: + int member; + int NODEREF *member2; + int NODEREF member3; // expected-warning{{'noderef' can only be used on an array or pointer type}} +}; + +void MemberPointer() { + int NODEREF A::*var = &A::member; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +template <class Ty> +class B { + Ty NODEREF *member; + Ty NODEREF member2; // expected-warning{{'noderef' can only be used on an array or pointer type}} +}; + +void test_lambdas() { + auto l = [](int NODEREF *x){ // expected-note{{x declared here}} + return *x; // expected-warning{{dereferencing x; was declared with a 'noderef' type}} + }; +} + +int NODEREF *glob_ptr; // expected-note{{glob_ptr declared here}} +int glob_int = *glob_ptr; // expected-warning{{dereferencing glob_ptr; was declared with a 'noderef' type}} diff --git a/test/Frontend/noderef_on_non_pointers.m b/test/Frontend/noderef_on_non_pointers.m new file mode 100644 index 000000000000..ced7627bb5e8 --- /dev/null +++ b/test/Frontend/noderef_on_non_pointers.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -verify %s + +#define NODEREF __attribute__((noderef)) + +@interface NSObject ++ (id)new; +@end + +void func() { + id NODEREF obj = [NSObject new]; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} diff --git a/test/Frontend/noderef_templates.cpp b/test/Frontend/noderef_templates.cpp new file mode 100644 index 000000000000..5fde6efd87c7 --- /dev/null +++ b/test/Frontend/noderef_templates.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify %s + +#define NODEREF __attribute__((noderef)) + +template <typename T> +int func(T NODEREF *a) { // expected-note 2 {{a declared here}} + return *a + 1; // expected-warning 2 {{dereferencing a; was declared with a 'noderef' type}} +} + +void func() { + float NODEREF *f; + int NODEREF *i; + func(f); // expected-note{{in instantiation of function template specialization 'func<float>' requested here}} + func(i); // expected-note{{in instantiation of function template specialization 'func<int>' requested here}} +} diff --git a/test/Frontend/optimization-remark-with-hotness.c b/test/Frontend/optimization-remark-with-hotness.c index 6d3ab0697a21..150b7324da5e 100644 --- a/test/Frontend/optimization-remark-with-hotness.c +++ b/test/Frontend/optimization-remark-with-hotness.c @@ -60,13 +60,13 @@ void bar(int x) { // THRESHOLD-NOT: hotness // NO_PGO: '-fdiagnostics-show-hotness' requires profile-guided optimization information // NO_PGO: '-fdiagnostics-hotness-threshold=' requires profile-guided optimization information - // expected-remark@+1 {{foo inlined into bar with cost=always (hotness:}} + // expected-remark@+1 {{foo inlined into bar with (cost=always): always inliner (hotness:}} sum += foo(x, x - 2); } int main(int argc, const char *argv[]) { for (int i = 0; i < 30; i++) - // expected-remark@+1 {{bar not inlined into main because it should never be inlined (cost=never) (hotness:}} + // expected-remark@+1 {{bar not inlined into main because it should never be inlined (cost=never): always inliner (hotness:}} bar(argc); return sum; } diff --git a/test/Frontend/plugin-unknown.c b/test/Frontend/plugin-unknown.c new file mode 100644 index 000000000000..5b225ae6639e --- /dev/null +++ b/test/Frontend/plugin-unknown.c @@ -0,0 +1,5 @@ +// RUN: not %clang_cc1 -plugin asdf %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -add-plugin asdf %s 2>&1 | FileCheck --check-prefix=ADD %s + +// CHECK: unable to find plugin 'asdf' +// ADD: unable to find plugin 'asdf' diff --git a/test/Frontend/warning-stdlibcxx-darwin.cpp b/test/Frontend/warning-stdlibcxx-darwin.cpp index 3c132b6a833b..697fe27c730d 100644 --- a/test/Frontend/warning-stdlibcxx-darwin.cpp +++ b/test/Frontend/warning-stdlibcxx-darwin.cpp @@ -1,5 +1,6 @@ // RUN: %clang -cc1 -triple arm64-apple-ios6.0.0 -isysroot %S/doesnotexist %s 2>&1 | FileCheck %s // RUN: %clang -cc1 -triple arm64-apple-ios6.0.0 -isysroot %S/doesnotexist -stdlib=libc++ %s -verify -// CHECK: include path for stdlibc++ headers not found; pass '-std=libc++' on the command line to use the libc++ standard library instead +// RUN: %clang -cc1 -x c++-cpp-output -triple arm64-apple-ios6.0.0 -isysroot %S/doesnotexist %s -verify +// CHECK: include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead // expected-no-diagnostics diff --git a/test/Frontend/windows-exceptions.cpp b/test/Frontend/windows-exceptions.cpp index 56316872be48..5aac32857c93 100644 --- a/test/Frontend/windows-exceptions.cpp +++ b/test/Frontend/windows-exceptions.cpp @@ -18,10 +18,10 @@ // RUN: %clang_cc1 -triple x86_64--windows-gnu -fsyntax-only -fseh-exceptions %s // RUN: %clang_cc1 -triple x86_64--windows-gnu -fsyntax-only -fsjlj-exceptions %s -// MSVC-X86-DWARF: error: invalid exception model 'fdwarf-exceptions' for target 'i686--windows-msvc' -// MSVC-X86-SEH: error: invalid exception model 'fseh-exceptions' for target 'i686--windows-msvc' -// MSVC-X86-SJLJ: error: invalid exception model 'fsjlj-exceptions' for target 'i686--windows-msvc' +// MSVC-X86-DWARF: error: invalid exception model 'fdwarf-exceptions' for target 'i686-unknown-windows-msvc' +// MSVC-X86-SEH: error: invalid exception model 'fseh-exceptions' for target 'i686-unknown-windows-msvc' +// MSVC-X86-SJLJ: error: invalid exception model 'fsjlj-exceptions' for target 'i686-unknown-windows-msvc' -// MSVC-X64-DWARF: error: invalid exception model 'fdwarf-exceptions' for target 'x86_64--windows-msvc' -// MSVC-X64-SEH: error: invalid exception model 'fseh-exceptions' for target 'x86_64--windows-msvc' -// MSVC-X64-SJLJ: error: invalid exception model 'fsjlj-exceptions' for target 'x86_64--windows-msvc' +// MSVC-X64-DWARF: error: invalid exception model 'fdwarf-exceptions' for target 'x86_64-unknown-windows-msvc' +// MSVC-X64-SEH: error: invalid exception model 'fseh-exceptions' for target 'x86_64-unknown-windows-msvc' +// MSVC-X64-SJLJ: error: invalid exception model 'fsjlj-exceptions' for target 'x86_64-unknown-windows-msvc' |
