1 // RUN: %clang_cc1 -fsyntax-only -Wno-pragma-clang-attribute -verify %s 2 // RUN: not %clang_cc1 -fsyntax-only -ast-dump -ast-dump-filter test %s | FileCheck %s 3 4 // Check for contradictions in rules for attribute without a strict subject set: 5 6 #pragma clang attribute push (__attribute__((annotate("subRuleContradictions"))), apply_to = any(variable, variable(is_parameter), function(is_member), variable(is_global))) 7 // expected-error@-1 {{redundant attribute subject matcher sub-rule 'variable(is_parameter)'; 'variable' already matches those declarations}} 8 // expected-error@-2 {{redundant attribute subject matcher sub-rule 'variable(is_global)'; 'variable' already matches those declarations}} 9 10 // Ensure that we've recovered from the error: 11 int testRecoverSubRuleContradiction = 0; 12 // CHECK-LABEL: VarDecl{{.*}} testRecoverSubRuleContradiction 13 // CHECK-NEXT: IntegerLiteral 14 // CHECK-NEXT: AnnotateAttr{{.*}} "subRuleContradictions" 15 16 #pragma clang attribute pop 17 18 #pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions2"))), apply_to = any(variable(unless(is_parameter)), variable(is_thread_local), function, variable(is_global))) 19 // expected-error@-1 {{negated attribute subject matcher sub-rule 'variable(unless(is_parameter))' contradicts sub-rule 'variable(is_global)'}} 20 // We have just one error, don't error on 'variable(is_global)' 21 22 // Ensure that we've recovered from the error: 23 int testRecoverNegatedContradiction = 0; 24 // CHECK-LABEL: VarDecl{{.*}} testRecoverNegatedContradiction 25 // CHECK-NEXT: IntegerLiteral 26 // CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2" 27 28 void testRecoverNegatedContradictionFunc(void); 29 // CHECK-LABEL: FunctionDecl{{.*}} testRecoverNegatedContradictionFunc 30 // CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2" 31 32 #pragma clang attribute pop 33 34 // Verify the strict subject set verification. 35 36 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function)) 37 38 int testRecoverStrictnessVar = 0; 39 // CHECK-LABEL: VarDecl{{.*}} testRecoverStrictnessVar 40 // CHECK-NEXT: IntegerLiteral 41 // CHECK-NOT: AbiTagAttr 42 43 void testRecoverStrictnessFunc(void); 44 // CHECK-LABEL: FunctionDecl{{.*}} testRecoverStrictnessFunc 45 // CHECK-NEXT: AbiTagAttr 46 47 struct testRecoverStrictnessStruct { }; 48 // CHECK-LABEL: RecordDecl{{.*}} testRecoverStrictnessStruct 49 // CHECK-NOT: AbiTagAttr 50 51 #pragma clang attribute pop 52 53 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum)) 54 // expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}} 55 56 int testRecoverExtraVar = 0; 57 // CHECK-LABEL: VarDecl{{.*}} testRecoverExtraVar 58 // CHECK-NEXT: IntegerLiteral 59 // CHECK-NEXT: AbiTagAttr 60 61 void testRecoverExtraFunc(void); 62 // CHECK-LABEL: FunctionDecl{{.*}} testRecoverExtraFunc 63 // CHECK-NEXT: AbiTagAttr 64 65 struct testRecoverExtraStruct { }; 66 // CHECK-LABEL: RecordDecl{{.*}} testRecoverExtraStruct 67 // CHECK-NEXT: AbiTagAttr 68 69 enum testNoEnumAbiTag { CaseCase }; 70 // CHECK-LABEL: EnumDecl{{.*}} testNoEnumAbiTag 71 // CHECK-NO: AbiTagAttr 72 73 #pragma clang attribute pop 74 75 // Verify the non-strict subject set verification. 76 77 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function)) 78 79 int testSubset1Var; 80 // CHECK-LABEL: VarDecl{{.*}} testSubset1Var 81 // CHECK-NOT: AbiTagAttr 82 83 void testSubset1Func(void); 84 // CHECK-LABEL: FunctionDecl{{.*}} testSubset1Func 85 // CHECK-NEXT: AbiTagAttr 86 87 struct testSubset1Struct { }; 88 // CHECK-LABEL: RecordDecl{{.*}} testSubset1Struct 89 // CHECK-NOT: AbiTagAttr 90 91 #pragma clang attribute pop 92 93 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable) 94 95 int testSubset2Var; 96 // CHECK-LABEL: VarDecl{{.*}} testSubset2Var 97 // CHECK-NEXT: AbiTagAttr 98 99 void testSubset2Func(void); 100 // CHECK-LABEL: FunctionDecl{{.*}} testSubset2Func 101 // CHECK-NOT: AbiTagAttr 102 103 struct testSubset2Struct { }; 104 // CHECK-LABEL: RecordDecl{{.*}} testSubset2Struct 105 // CHECK-NOT: AbiTagAttr 106 107 #pragma clang attribute pop 108 109 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)))) 110 111 int testSubset3Var; 112 // CHECK-LABEL: VarDecl{{.*}} testSubset3Var 113 // CHECK-NOT: AbiTagAttr 114 115 void testSubset3Func(void); 116 // CHECK-LABEL: FunctionDecl{{.*}} testSubset3Func 117 // CHECK-NOT: AbiTagAttr 118 119 struct testSubset3Struct { }; 120 // CHECK-LABEL: RecordDecl{{.*}} testSubset3Struct 121 // CHECK-NEXT: AbiTagAttr 122 123 #pragma clang attribute pop 124 125 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable)) 126 127 int testSubset4Var; 128 // CHECK-LABEL: VarDecl{{.*}} testSubset4Var 129 // CHECK-NEXT: AbiTagAttr 130 131 void testSubset4Func(void); 132 // CHECK-LABEL: FunctionDecl{{.*}} testSubset4Func 133 // CHECK-NEXT: AbiTagAttr 134 135 struct testSubset4Struct { }; 136 // CHECK-LABEL: RecordDecl{{.*}} testSubset4Struct 137 // CHECK-NOT: AbiTagAttr 138 139 #pragma clang attribute pop 140 141 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)))) 142 143 int testSubset5Var; 144 // CHECK-LABEL: VarDecl{{.*}} testSubset5Var 145 // CHECK-NEXT: AbiTagAttr 146 147 void testSubset5Func(void); 148 // CHECK-LABEL: FunctionDecl{{.*}} testSubset5Func 149 // CHECK-NOT: AbiTagAttr 150 151 struct testSubset5Struct { }; 152 // CHECK-LABEL: RecordDecl{{.*}} testSubset5Struct 153 // CHECK-NEXT: AbiTagAttr 154 155 #pragma clang attribute pop 156 157 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function)) 158 159 int testSubset6Var; 160 // CHECK-LABEL: VarDecl{{.*}} testSubset6Var 161 // CHECK-NOT: AbiTagAttr 162 163 void testSubset6Func(void); 164 // CHECK-LABEL: FunctionDecl{{.*}} testSubset6Func 165 // CHECK-NEXT: AbiTagAttr 166 167 struct testSubset6Struct { }; 168 // CHECK-LABEL: RecordDecl{{.*}} testSubset6Struct 169 // CHECK-NEXT: AbiTagAttr 170 171 #pragma clang attribute pop 172 173 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable)) 174 175 int testSubset7Var; 176 // CHECK-LABEL: VarDecl{{.*}} testSubset7Var 177 // CHECK-NEXT: AbiTagAttr 178 179 void testSubset7Func(void); 180 // CHECK-LABEL: FunctionDecl{{.*}} testSubset7Func 181 // CHECK-NEXT: AbiTagAttr 182 183 struct testSubset7Struct { }; 184 // CHECK-LABEL: RecordDecl{{.*}} testSubset7Struct 185 // CHECK-NEXT: AbiTagAttr 186 187 #pragma clang attribute pop 188 189 190 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant)) 191 // expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum_constant', and 'enum'}} 192 193 int testSubsetRecoverVar; 194 // CHECK-LABEL: VarDecl{{.*}} testSubsetRecoverVar 195 // CHECK-NEXT: AbiTagAttr 196 197 void testSubsetRecoverFunc(void); 198 // CHECK-LABEL: FunctionDecl{{.*}} testSubsetRecoverFunc 199 // CHECK-NEXT: AbiTagAttr 200 201 struct testSubsetRecoverStruct { }; 202 // CHECK-LABEL: RecordDecl{{.*}} testSubsetRecoverStruct 203 // CHECK-NEXT: AbiTagAttr 204 205 #pragma clang attribute pop 206 207 #pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = enum) 208 // expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}} 209 210 int testSubsetNoVar; 211 // CHECK-LABEL: VarDecl{{.*}} testSubsetNoVar 212 // CHECK-NOT: AbiTagAttr 213 214 void testSubsetNoFunc(void); 215 // CHECK-LABEL: FunctionDecl{{.*}} testSubsetNoFunc 216 // CHECK-NOT: AbiTagAttr 217 218 struct testSubsetNoStruct { }; 219 // CHECK-LABEL: RecordDecl{{.*}} testSubsetNoStruct 220 // CHECK-NOT: AbiTagAttr 221 222 #pragma clang attribute pop 223