Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s
      2 
      3 #pragma clang optimize off
      4 
      5 // This is a macro definition and therefore its text is not present after
      6 // preprocessing. The pragma has no effect here.
      7 #define CREATE_FUNC(name)        \
      8 int name (int param) {           \
      9     return param;                \
     10 }                                \
     11 
     12 // This is a declaration and therefore it is not decorated with `optnone`.
     13 extern int foo(int a, int b);
     14 // CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]]
     15 
     16 // This is a definition and therefore it will be decorated with `optnone`.
     17 int bar(int x, int y) {
     18     for(int i = 0; i < x; ++i)
     19         y += x;
     20     return y + foo(x, y);
     21 }
     22 // CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]]
     23 
     24 // The function "int created (int param)" created by the macro invocation
     25 // is also decorated with the `optnone` attribute because it is within a
     26 // region of code affected by the functionality (not because of the position
     27 // of the macro definition).
     28 CREATE_FUNC (created)
     29 // CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]]
     30 
     31 class MyClass {
     32     public:
     33         // The declaration of the method is not decorated with `optnone`.
     34         int method(int blah);
     35 };
     36 
     37 // The definition of the method instead is decorated with `optnone`.
     38 int MyClass::method(int blah) {
     39     return blah + 1;
     40 }
     41 // CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]]
     42 
     43 // A template declaration will not be decorated with `optnone`.
     44 template <typename T> T twice (T param);
     45 
     46 // The template definition will be decorated with the attribute `optnone`.
     47 template <typename T> T thrice (T param) {
     48     return 3 * param;
     49 }
     50 
     51 // This function definition will not be decorated with `optnone` because the
     52 // attribute would conflict with `always_inline`.
     53 int __attribute__((always_inline)) baz(int z) {
     54     return foo(z, 2);
     55 }
     56 // CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]]
     57 
     58 #pragma clang optimize on
     59 
     60 // The function "int wombat(int param)" created by the macro is not
     61 // decorated with `optnone`, because the pragma applies its effects only
     62 // after preprocessing. The position of the macro definition is not
     63 // relevant.
     64 CREATE_FUNC (wombat)
     65 // CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]]
     66 
     67 // This instantiation of the "twice" template function with a "float" type
     68 // will not have an `optnone` attribute because the template declaration was
     69 // not affected by the pragma.
     70 float container (float par) {
     71     return twice(par);
     72 }
     73 // CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]]
     74 // CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]]
     75 
     76 // This instantiation of the "thrice" template function with a "float" type
     77 // will have an `optnone` attribute because the template definition was
     78 // affected by the pragma.
     79 float container2 (float par) {
     80     return thrice(par);
     81 }
     82 // CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]]
     83 // CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]]
     84 
     85 
     86 // A template specialization is a new definition and it will not be
     87 // decorated with an `optnone` attribute because it is now outside of the
     88 // affected region.
     89 template<> int thrice(int par) {
     90     return (par << 1) + par;
     91 }
     92 int container3 (int par) {
     93     return thrice(par);
     94 }
     95 // CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]]
     96 // CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]]
     97 
     98 
     99 // Check for both noinline and optnone on each function that should have them.
    100 // CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
    101 // CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
    102 // CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
    103 // CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
    104 
    105 // Check that the other functions do NOT have optnone.
    106 // CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} }
    107 // CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} }
    108 // CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} }
    109 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} }
    110 // CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} }
    111 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} }
    112 // CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} }
    113 // CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} }
    114