diff options
Diffstat (limited to 'clang/test/SemaCXX/pragma-optimize.cpp')
-rw-r--r-- | clang/test/SemaCXX/pragma-optimize.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/pragma-optimize.cpp b/clang/test/SemaCXX/pragma-optimize.cpp new file mode 100644 index 00000000000..390070a8262 --- /dev/null +++ b/clang/test/SemaCXX/pragma-optimize.cpp @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm -O2 < %s | FileCheck %s + +#pragma clang optimize off + +// This is a macro definition and therefore its text is not present after +// preprocessing. The pragma has no effect here. +#define CREATE_FUNC(name) \ +int name (int param) { \ + return param; \ +} \ + +// This is a declaration and therefore it is not decorated with `optnone`. +extern int foo(int a, int b); +// CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]] + +// This is a definition and therefore it will be decorated with `optnone`. +int bar(int x, int y) { + for(int i = 0; i < x; ++i) + y += x; + return y + foo(x, y); +} +// CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]] + +// The function "int created (int param)" created by the macro invocation +// is also decorated with the `optnone` attribute because it is within a +// region of code affected by the functionality (not because of the position +// of the macro definition). +CREATE_FUNC (created) +// CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]] + +class MyClass { + public: + // The declaration of the method is not decorated with `optnone`. + int method(int blah); +}; + +// The definition of the method instead is decorated with `optnone`. +int MyClass::method(int blah) { + return blah + 1; +} +// CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]] + +// A template declaration will not be decorated with `optnone`. +template <typename T> T twice (T param); + +// The template definition will be decorated with the attribute `optnone`. +template <typename T> T thrice (T param) { + return 3 * param; +} + +// This function definition will not be decorated with `optnone` because the +// attribute would conflict with `always_inline`. +int __attribute__((always_inline)) baz(int z) { + return foo(z, 2); +} +// CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]] + +#pragma clang optimize on + +// The function "int wombat(int param)" created by the macro is not +// decorated with `optnone`, because the pragma applies its effects only +// after preprocessing. The position of the macro definition is not +// relevant. +CREATE_FUNC (wombat) +// CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]] + +// This instantiation of the "twice" template function with a "float" type +// will not have an `optnone` attribute because the template declaration was +// not affected by the pragma. +float container (float par) { + return twice(par); +} +// CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]] +// CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]] + +// This instantiation of the "thrice" template function with a "float" type +// will have an `optnone` attribute because the template definition was +// affected by the pragma. +float container2 (float par) { + return thrice(par); +} +// CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]] +// CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]] + + +// A template specialization is a new definition and it will not be +// decorated with an `optnone` attribute because it is now outside of the +// affected region. +template<> int thrice(int par) { + return (par << 1) + par; +} +int container3 (int par) { + return thrice(par); +} +// CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]] +// CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]] + + +// Check for both noinline and optnone on each function that should have them. +// CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} } +// CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} } +// CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} } +// CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} } + +// Check that the other functions do NOT have optnone. +// CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} } +// CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} } |