223 lines · c
1// RUN: %clang_cc1 -fsyntax-only -Wno-pragma-clang-attribute -verify %s2// RUN: not %clang_cc1 -ast-dump -ast-dump-filter test %s | FileCheck %s3 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:11int testRecoverSubRuleContradiction = 0;12// CHECK-LABEL: VarDecl{{.*}} testRecoverSubRuleContradiction13// CHECK-NEXT: IntegerLiteral14// CHECK-NEXT: AnnotateAttr{{.*}} "subRuleContradictions"15 16#pragma clang attribute pop17 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:23int testRecoverNegatedContradiction = 0;24// CHECK-LABEL: VarDecl{{.*}} testRecoverNegatedContradiction25// CHECK-NEXT: IntegerLiteral26// CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2"27 28void testRecoverNegatedContradictionFunc(void);29// CHECK-LABEL: FunctionDecl{{.*}} testRecoverNegatedContradictionFunc30// CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2"31 32#pragma clang attribute pop33 34// Verify the strict subject set verification.35 36#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))37 38int testRecoverStrictnessVar = 0;39// CHECK-LABEL: VarDecl{{.*}} testRecoverStrictnessVar40// CHECK-NEXT: IntegerLiteral41// CHECK-NOT: AbiTagAttr42 43void testRecoverStrictnessFunc(void);44// CHECK-LABEL: FunctionDecl{{.*}} testRecoverStrictnessFunc45// CHECK-NEXT: AbiTagAttr46 47struct testRecoverStrictnessStruct { };48// CHECK-LABEL: RecordDecl{{.*}} testRecoverStrictnessStruct49// CHECK-NOT: AbiTagAttr50 51#pragma clang attribute pop52 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' cannot be applied to 'enum'}}55 56int testRecoverExtraVar = 0;57// CHECK-LABEL: VarDecl{{.*}} testRecoverExtraVar58// CHECK-NEXT: IntegerLiteral59// CHECK-NEXT: AbiTagAttr60 61void testRecoverExtraFunc(void);62// CHECK-LABEL: FunctionDecl{{.*}} testRecoverExtraFunc63// CHECK-NEXT: AbiTagAttr64 65struct testRecoverExtraStruct { };66// CHECK-LABEL: RecordDecl{{.*}} testRecoverExtraStruct67// CHECK-NEXT: AbiTagAttr68 69enum testNoEnumAbiTag { CaseCase };70// CHECK-LABEL: EnumDecl{{.*}} testNoEnumAbiTag71// CHECK-NO: AbiTagAttr72 73#pragma clang attribute pop74 75// Verify the non-strict subject set verification.76 77#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))78 79int testSubset1Var;80// CHECK-LABEL: VarDecl{{.*}} testSubset1Var81// CHECK-NOT: AbiTagAttr82 83void testSubset1Func(void);84// CHECK-LABEL: FunctionDecl{{.*}} testSubset1Func85// CHECK-NEXT: AbiTagAttr86 87struct testSubset1Struct { };88// CHECK-LABEL: RecordDecl{{.*}} testSubset1Struct89// CHECK-NOT: AbiTagAttr90 91#pragma clang attribute pop92 93#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable)94 95int testSubset2Var;96// CHECK-LABEL: VarDecl{{.*}} testSubset2Var97// CHECK-NEXT: AbiTagAttr98 99void testSubset2Func(void);100// CHECK-LABEL: FunctionDecl{{.*}} testSubset2Func101// CHECK-NOT: AbiTagAttr102 103struct testSubset2Struct { };104// CHECK-LABEL: RecordDecl{{.*}} testSubset2Struct105// CHECK-NOT: AbiTagAttr106 107#pragma clang attribute pop108 109#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union))))110 111int testSubset3Var;112// CHECK-LABEL: VarDecl{{.*}} testSubset3Var113// CHECK-NOT: AbiTagAttr114 115void testSubset3Func(void);116// CHECK-LABEL: FunctionDecl{{.*}} testSubset3Func117// CHECK-NOT: AbiTagAttr118 119struct testSubset3Struct { };120// CHECK-LABEL: RecordDecl{{.*}} testSubset3Struct121// CHECK-NEXT: AbiTagAttr122 123#pragma clang attribute pop124 125#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable))126 127int testSubset4Var;128// CHECK-LABEL: VarDecl{{.*}} testSubset4Var129// CHECK-NEXT: AbiTagAttr130 131void testSubset4Func(void);132// CHECK-LABEL: FunctionDecl{{.*}} testSubset4Func133// CHECK-NEXT: AbiTagAttr134 135struct testSubset4Struct { };136// CHECK-LABEL: RecordDecl{{.*}} testSubset4Struct137// CHECK-NOT: AbiTagAttr138 139#pragma clang attribute pop140 141#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union))))142 143int testSubset5Var;144// CHECK-LABEL: VarDecl{{.*}} testSubset5Var145// CHECK-NEXT: AbiTagAttr146 147void testSubset5Func(void);148// CHECK-LABEL: FunctionDecl{{.*}} testSubset5Func149// CHECK-NOT: AbiTagAttr150 151struct testSubset5Struct { };152// CHECK-LABEL: RecordDecl{{.*}} testSubset5Struct153// CHECK-NEXT: AbiTagAttr154 155#pragma clang attribute pop156 157#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function))158 159int testSubset6Var;160// CHECK-LABEL: VarDecl{{.*}} testSubset6Var161// CHECK-NOT: AbiTagAttr162 163void testSubset6Func(void);164// CHECK-LABEL: FunctionDecl{{.*}} testSubset6Func165// CHECK-NEXT: AbiTagAttr166 167struct testSubset6Struct { };168// CHECK-LABEL: RecordDecl{{.*}} testSubset6Struct169// CHECK-NEXT: AbiTagAttr170 171#pragma clang attribute pop172 173#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable))174 175int testSubset7Var;176// CHECK-LABEL: VarDecl{{.*}} testSubset7Var177// CHECK-NEXT: AbiTagAttr178 179void testSubset7Func(void);180// CHECK-LABEL: FunctionDecl{{.*}} testSubset7Func181// CHECK-NEXT: AbiTagAttr182 183struct testSubset7Struct { };184// CHECK-LABEL: RecordDecl{{.*}} testSubset7Struct185// CHECK-NEXT: AbiTagAttr186 187#pragma clang attribute pop188 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' cannot be applied to 'enum_constant', and 'enum'}}192 193int testSubsetRecoverVar;194// CHECK-LABEL: VarDecl{{.*}} testSubsetRecoverVar195// CHECK-NEXT: AbiTagAttr196 197void testSubsetRecoverFunc(void);198// CHECK-LABEL: FunctionDecl{{.*}} testSubsetRecoverFunc199// CHECK-NEXT: AbiTagAttr200 201struct testSubsetRecoverStruct { };202// CHECK-LABEL: RecordDecl{{.*}} testSubsetRecoverStruct203// CHECK-NEXT: AbiTagAttr204 205#pragma clang attribute pop206 207#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = enum)208// expected-error@-1 {{attribute 'abi_tag' cannot be applied to 'enum'}}209 210int testSubsetNoVar;211// CHECK-LABEL: VarDecl{{.*}} testSubsetNoVar212// CHECK-NOT: AbiTagAttr213 214void testSubsetNoFunc(void);215// CHECK-LABEL: FunctionDecl{{.*}} testSubsetNoFunc216// CHECK-NOT: AbiTagAttr217 218struct testSubsetNoStruct { };219// CHECK-LABEL: RecordDecl{{.*}} testSubsetNoStruct220// CHECK-NOT: AbiTagAttr221 222#pragma clang attribute pop223