165 lines · cpp
1// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -emit-llvm -x c++ | FileCheck %s2 3// Test attribute 'optnone' on methods:4// -- member functions;5// -- static member functions.6 7// Verify that all methods of struct A are associated to the same attribute set.8// The attribute set shall contain attributes 'noinline' and 'optnone'.9 10struct A {11 // Definition of an optnone static method.12 __attribute__((optnone))13 static int static_optnone_method(int a) {14 return a + a;15 }16 // CHECK: @_ZN1A21static_optnone_methodEi({{.*}}) [[OPTNONE:#[0-9]+]]17 18 // Definition of an optnone normal method.19 __attribute__((optnone))20 int optnone_method(int a) {21 return a + a + a + a;22 }23 // CHECK: @_ZN1A14optnone_methodEi({{.*}}) [[OPTNONE]]24 25 // Declaration of an optnone method with out-of-line definition26 // that doesn't say optnone.27 __attribute__((optnone))28 int optnone_decl_method(int a);29 30 // Methods declared without attribute optnone; the definitions will31 // have attribute optnone, and we verify optnone wins.32 __forceinline static int static_forceinline_method(int a);33 __attribute__((always_inline)) int alwaysinline_method(int a);34 __attribute__((noinline)) int noinline_method(int a);35 __attribute__((minsize)) int minsize_method(int a);36};37 38void foo() {39 A a;40 A::static_optnone_method(4);41 a.optnone_method(14);42 a.optnone_decl_method(12);43 A::static_forceinline_method(5);44 a.alwaysinline_method(5);45 a.noinline_method(6);46 a.minsize_method(7);47}48 49// No attribute here, should still be on the definition.50int A::optnone_decl_method(int a) {51 return a;52}53// CHECK: @_ZN1A19optnone_decl_methodEi({{.*}}) [[OPTNONE]]54 55// optnone implies noinline; therefore attribute noinline is added to56// the set of function attributes.57// forceinline is instead translated as 'always_inline'.58// However 'noinline' wins over 'always_inline' and therefore59// the resulting attributes for this method are: noinline + optnone60__attribute__((optnone))61int A::static_forceinline_method(int a) {62 return a + a + a + a;63}64// CHECK: @_ZN1A25static_forceinline_methodEi({{.*}}) [[OPTNONE]]65 66__attribute__((optnone))67int A::alwaysinline_method(int a) {68 return a + a + a + a;69}70// CHECK: @_ZN1A19alwaysinline_methodEi({{.*}}) [[OPTNONE]]71 72// 'noinline' + 'noinline and optnone' = 'noinline and optnone'73__attribute__((optnone))74int A::noinline_method(int a) {75 return a + a + a + a;76}77// CHECK: @_ZN1A15noinline_methodEi({{.*}}) [[OPTNONE]]78 79// 'optnone' wins over 'minsize'80__attribute__((optnone))81int A::minsize_method(int a) {82 return a + a + a + a;83}84// CHECK: @_ZN1A14minsize_methodEi({{.*}}) [[OPTNONE]]85 86 87// Test attribute 'optnone' on methods:88// -- pure virtual functions89// -- base virtual and derived virtual90// -- base virtual but not derived virtual91// -- optnone methods redefined in override92 93// A method defined in override doesn't inherit the function attributes of the94// superclass method.95 96struct B {97 virtual int pure_virtual(int a) = 0;98 __attribute__((optnone))99 virtual int pure_virtual_with_optnone(int a) = 0;100 101 virtual int base(int a) {102 return a + a + a + a;103 }104 105 __attribute__((optnone))106 virtual int optnone_base(int a) {107 return a + a + a + a;108 }109 110 __attribute__((optnone))111 virtual int only_base_virtual(int a) {112 return a + a;113 }114};115 116struct C : public B {117 __attribute__((optnone))118 virtual int pure_virtual(int a) {119 return a + a + a + a;120 }121 122 virtual int pure_virtual_with_optnone(int a) {123 return a + a + a + a;124 }125 126 __attribute__((optnone))127 virtual int base(int a) {128 return a + a;129 }130 131 virtual int optnone_base(int a) {132 return a + a;133 }134 135 int only_base_virtual(int a) {136 return a + a + a + a;137 }138};139 140int bar() {141 C c;142 int result;143 result = c.pure_virtual(3);144 result += c.pure_virtual_with_optnone(2);145 result += c.base(5);146 result += c.optnone_base(7);147 result += c.only_base_virtual(9);148 return result;149}150 151// CHECK: @_ZN1C12pure_virtualEi({{.*}}) {{.*}} [[OPTNONE]]152// CHECK: @_ZN1C25pure_virtual_with_optnoneEi({{.*}}) {{.*}} [[NORMAL:#[0-9]+]]153// CHECK: @_ZN1C4baseEi({{.*}}) {{.*}} [[OPTNONE]]154// CHECK: @_ZN1C12optnone_baseEi({{.*}}) {{.*}} [[NORMAL]]155// CHECK: @_ZN1C17only_base_virtualEi({{.*}}) {{.*}} [[NORMAL]]156// CHECK: @_ZN1B4baseEi({{.*}}) {{.*}} [[NORMAL]]157// CHECK: @_ZN1B12optnone_baseEi({{.*}}) {{.*}} [[OPTNONE]]158// CHECK: @_ZN1B17only_base_virtualEi({{.*}}) {{.*}} [[OPTNONE]]159 160 161// CHECK: attributes [[NORMAL]] =162// CHECK-NOT: noinline163// CHECK-NOT: optnone164// CHECK: attributes [[OPTNONE]] = {{.*}} noinline {{.*}} optnone165