Author: Nico Weber Date: 2021-01-11T09:51:06-05:00 New Revision: 419ef38a50293c58078f830517f5e305068dbee6
URL: https://github.com/llvm/llvm-project/commit/419ef38a50293c58078f830517f5e305068dbee6 DIFF: https://github.com/llvm/llvm-project/commit/419ef38a50293c58078f830517f5e305068dbee6.diff LOG: Revert "[attributes] Add a facility for enforcing a Trusted Computing Base." This reverts commit c163aae45ef6b7f3bd99601195d3ce4aad5850c6. Doesn't compile on some bots (http://lab.llvm.org:8011/#/builders/98/builds/3387/steps/9/logs/stdio), breaks tests on bots where it does compile (http://45.33.8.238/linux/36843/step_7.txt). Added: Modified: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp Removed: clang/test/Sema/attr-enforce-tcb-errors.cpp clang/test/Sema/attr-enforce-tcb.c clang/test/Sema/attr-enforce-tcb.cpp ################################################################################ diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index c51e95fa6fa8..248409946123 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3653,19 +3653,3 @@ def Builtin : InheritableAttr { let SemaHandler = 0; let Documentation = [Undocumented]; } - -def EnforceTCB : InheritableAttr { - let Spellings = [Clang<"enforce_tcb">]; - let Subjects = SubjectList<[Function]>; - let Args = [StringArgument<"TCBName">]; - let Documentation = [EnforceTCBDocs]; - bit InheritEvenIfAlreadyPresent = 1; -} - -def EnforceTCBLeaf : InheritableAttr { - let Spellings = [Clang<"enforce_tcb_leaf">]; - let Subjects = SubjectList<[Function]>; - let Args = [StringArgument<"TCBName">]; - let Documentation = [EnforceTCBLeafDocs]; - bit InheritEvenIfAlreadyPresent = 1; -} diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fffede41db1e..9cf0c59e07bb 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5725,28 +5725,3 @@ Attribute docs`_, and `the GCC Inline docs`_. }]; let Heading = "always_inline, __force_inline"; } - -def EnforceTCBDocs : Documentation { - let Category = DocCatFunction; - let Content = [{ - The ``enforce_tcb`` attribute can be placed on functions to enforce that a - trusted compute base (TCB) does not call out of the TCB. This generates a - warning every time a function not marked with an ``enforce_tcb`` attribute is - called from a function with the ``enforce_tcb`` attribute. A function may be a - part of multiple TCBs. Invocations through function pointers are currently - not checked. Builtins are considered to a part of every TCB. - - - ``enforce_tcb(Name)`` indicates that this function is a part of the TCB named ``Name`` - }]; -} - -def EnforceTCBLeafDocs : Documentation { - let Category = DocCatFunction; - let Content = [{ - The ``enforce_tcb_leaf`` attribute satisfies the requirement enforced by - ``enforce_tcb`` for the marked function to be in the named TCB but does not - continue to check the functions called from within the leaf function. - - - ``enforce_tcb_leaf(Name)`` indicates that this function is a part of the TCB named ``Name`` - }]; -} diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c048fc89813f..0405195912b2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11116,11 +11116,4 @@ def err_probability_not_constant_float : Error< def err_probability_out_of_range : Error< "probability argument to __builtin_expect_with_probability is outside the " "range [0.0, 1.0]">; - -// TCB warnings -def err_tcb_conflicting_attributes : Error< - "attributes '%0(\"%2\")' and '%1(\"%2\")' are mutually exclusive">; -def warn_tcb_enforcement_violation : Warning< - "calling %0 is a violation of trusted computing base '%1'">, - InGroup<DiagGroup<"tcb-enforcement">>; } // end of sema component. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4de3b962c660..1d79e5716ef7 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3210,9 +3210,6 @@ class Sema final { Decl *D, const WebAssemblyImportNameAttr &AL); WebAssemblyImportModuleAttr *mergeImportModuleAttr( Decl *D, const WebAssemblyImportModuleAttr &AL); - EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL); - EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D, - const EnforceTCBLeafAttr &AL); void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AMK_Redeclaration); @@ -12430,8 +12427,6 @@ class Sema final { /// attempts to add itself into the container void CheckObjCCircularContainer(ObjCMessageExpr *Message); - void CheckTCBEnforcement(const CallExpr *TheCall, const FunctionDecl *Callee); - void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE); void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, bool DeleteWasArrayForm); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 440b0a38481b..7e83a39b16ab 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -75,7 +75,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/AtomicOrdering.h" @@ -4570,8 +4569,6 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, if (!FnInfo) return false; - CheckTCBEnforcement(TheCall, FDecl); - CheckAbsoluteValueFunction(TheCall, FDecl); CheckMaxUnsignedZero(TheCall, FDecl); @@ -16062,37 +16059,3 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, return CallResult; } - -/// \brief Enforce the bounds of a TCB -/// CheckTCBEnforcement - Enforces that every function in a named TCB only -/// directly calls other functions in the same TCB as marked by the enforce_tcb -/// and enforce_tcb_leaf attributes. -void Sema::CheckTCBEnforcement(const CallExpr *TheCall, - const FunctionDecl *Callee) { - const FunctionDecl *Caller = getCurFunctionDecl(); - - // Calls to builtins are not enforced. - if (!Caller || !Caller->hasAttr<EnforceTCBAttr>() || - Callee->getBuiltinID() != 0) - return; - - // Search through the enforce_tcb and enforce_tcb_leaf attributes to find - // all TCBs the callee is a part of. - llvm::StringSet<> CalleeTCBs; - for_each(Callee->specific_attrs<EnforceTCBAttr>(), - [&](const auto *A) { CalleeTCBs.insert(A->getTCBName()); }); - for_each(Callee->specific_attrs<EnforceTCBLeafAttr>(), - [&](const auto *A) { CalleeTCBs.insert(A->getTCBName()); }); - - // Go through the TCBs the caller is a part of and emit warnings if Caller - // is in a TCB that the Callee is not. - for_each( - Caller->specific_attrs<EnforceTCBAttr>(), - [&](const auto *A) { - StringRef CallerTCB = A->getTCBName(); - if (CalleeTCBs.count(CallerTCB) == 0) { - Diag(TheCall->getExprLoc(), diag::warn_tcb_enforcement_violation) - << Callee << CallerTCB; - } - }); -} diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3cd32f894bd1..dd31f3f98487 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2612,10 +2612,6 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.mergeImportModuleAttr(D, *IMA); else if (const auto *INA = dyn_cast<WebAssemblyImportNameAttr>(Attr)) NewAttr = S.mergeImportNameAttr(D, *INA); - else if (const auto *TCBA = dyn_cast<EnforceTCBAttr>(Attr)) - NewAttr = S.mergeEnforceTCBAttr(D, *TCBA); - else if (const auto *TCBLA = dyn_cast<EnforceTCBLeafAttr>(Attr)) - NewAttr = S.mergeEnforceTCBLeafAttr(D, *TCBLA); else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index bd8ec2bdef76..0872cc640b39 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7517,75 +7517,6 @@ static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg)); } - -template <typename AttrTy> -static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) { - auto Attrs = D->specific_attrs<AttrTy>(); - auto I = llvm::find_if(Attrs, - [Name](const AttrTy *A) { - return A->getTCBName() == Name; - }); - return I == Attrs.end() ? nullptr : *I; -} - -template <typename AttrTy, typename ConflictingAttrTy> -static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - StringRef Argument; - if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument)) - return; - - // A function cannot be have both regular and leaf membership in the same TCB. - if (const ConflictingAttrTy *ConflictingAttr = - findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) { - // We could attach a note to the other attribute but in this case - // there's no need given how the two are very close to each other. - S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes) - << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName() - << Argument; - - // Error recovery: drop the non-leaf attribute so that to suppress - // all future warnings caused by erroneous attributes. The leaf attribute - // needs to be kept because it can only suppresses warnings, not cause them. - D->dropAttr<EnforceTCBAttr>(); - return; - } - - D->addAttr(AttrTy::Create(S.Context, Argument, AL)); -} - -template <typename AttrTy, typename ConflictingAttrTy> -static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) { - // Check if the new redeclaration has diff erent leaf-ness in the same TCB. - StringRef TCBName = AL.getTCBName(); - if (const ConflictingAttrTy *ConflictingAttr = - findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) { - S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes) - << ConflictingAttr->getAttrName()->getName() - << AL.getAttrName()->getName() << TCBName; - - // Add a note so that the user could easily find the conflicting attribute. - S.Diag(AL.getLoc(), diag::note_conflicting_attribute); - - // More error recovery. - D->dropAttr<EnforceTCBAttr>(); - return nullptr; - } - - ASTContext &Context = S.getASTContext(); - return ::new(Context) AttrTy(Context, AL, AL.getTCBName()); -} - -EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) { - return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>( - *this, D, AL); -} - -EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr( - Decl *D, const EnforceTCBLeafAttr &AL) { - return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>( - *this, D, AL); -} - //===----------------------------------------------------------------------===// // Top Level Sema Entry Points //===----------------------------------------------------------------------===// @@ -8289,14 +8220,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_UseHandle: handleHandleAttr<UseHandleAttr>(S, D, AL); break; - - case ParsedAttr::AT_EnforceTCB: - handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL); - break; - - case ParsedAttr::AT_EnforceTCBLeaf: - handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL); - break; } } diff --git a/clang/test/Sema/attr-enforce-tcb-errors.cpp b/clang/test/Sema/attr-enforce-tcb-errors.cpp deleted file mode 100644 index 1ce147ab32df..000000000000 --- a/clang/test/Sema/attr-enforce-tcb-errors.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -[[clang::enforce_tcb("oops")]] int wrong_subject_type; // expected-warning{{'enforce_tcb' attribute only applies to functions}} - -void no_arguments() __attribute__((enforce_tcb)); // expected-error{{'enforce_tcb' attribute takes one argument}} - -void too_many_arguments() __attribute__((enforce_tcb("test", 12))); // expected-error{{'enforce_tcb' attribute takes one argument}} - -void wrong_argument_type() __attribute__((enforce_tcb(12))); // expected-error{{'enforce_tcb' attribute requires a string}} - -[[clang::enforce_tcb_leaf("oops")]] int wrong_subject_type_leaf; // expected-warning{{'enforce_tcb_leaf' attribute only applies to functions}} - -void no_arguments_leaf() __attribute__((enforce_tcb_leaf)); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}} - -void too_many_arguments_leaf() __attribute__((enforce_tcb_leaf("test", 12))); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}} -void wrong_argument_type_leaf() __attribute__((enforce_tcb_leaf(12))); // expected-error{{'enforce_tcb_leaf' attribute requires a string}} - -void foo(); - -__attribute__((enforce_tcb("x"))) -__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}} -void both_tcb_and_tcb_leaf() { - foo(); // no-warning -} - -__attribute__((enforce_tcb_leaf("x"))) // expected-note{{conflicting attribute is here}} -void both_tcb_and_tcb_leaf_on_separate_redeclarations(); -__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}} -void both_tcb_and_tcb_leaf_on_separate_redeclarations() { - // Error recovery: no need to emit a warning when we didn't - // figure out our attributes to begin with. - foo(); // no-warning -} - -__attribute__((enforce_tcb_leaf("x"))) -__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}} -void both_tcb_and_tcb_leaf_opposite_order() { - foo(); // no-warning -} - -__attribute__((enforce_tcb("x"))) // expected-note{{conflicting attribute is here}} -void both_tcb_and_tcb_leaf_on_separate_redeclarations_opposite_order(); -__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}} -void both_tcb_and_tcb_leaf_on_separate_redeclarations_opposite_order() { - foo(); // no-warning -} - -__attribute__((enforce_tcb("x"))) -__attribute__((enforce_tcb_leaf("y"))) // no-error -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers() { - foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}} -} -__attribute__((enforce_tcb_leaf("x"))) -__attribute__((enforce_tcb("y"))) // no-error -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers_opposite_order() { - foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}} -} - -__attribute__((enforce_tcb("x"))) -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers_on_separate_redeclarations(); -__attribute__((enforce_tcb_leaf("y"))) // no-error -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers_on_separate_redeclarations() { - foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}} -} - -__attribute__((enforce_tcb_leaf("x"))) -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers_on_separate_redeclarations_opposite_order(); -__attribute__((enforce_tcb("y"))) -void both_tcb_and_tcb_leaf_but_ diff erent_identifiers_on_separate_redeclarations_opposite_order() { - foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}} -} - -__attribute__((enforce_tcb("y"))) -__attribute__((enforce_tcb("x"))) -__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}} -void error_recovery_over_individual_tcbs() { - // FIXME: Ideally this should warn. The conflict between attributes - // for TCB "x" shouldn't affect the warning about TCB "y". - foo(); // no-warning -} diff --git a/clang/test/Sema/attr-enforce-tcb.c b/clang/test/Sema/attr-enforce-tcb.c deleted file mode 100644 index 2807f770ce73..000000000000 --- a/clang/test/Sema/attr-enforce-tcb.c +++ /dev/null @@ -1,65 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#define PLACE_IN_TCB(NAME) __attribute__ ((enforce_tcb(NAME))) -#define PLACE_IN_TCB_LEAF(NAME) __attribute__ ((enforce_tcb_leaf(NAME))) - -void foo1 (void) PLACE_IN_TCB("bar"); -void foo2 (void) PLACE_IN_TCB("bar"); -void foo3 (void); // not in any TCB -void foo4 (void) PLACE_IN_TCB("bar2"); -void foo5 (void) PLACE_IN_TCB_LEAF("bar"); -void foo6 (void) PLACE_IN_TCB("bar2") PLACE_IN_TCB("bar"); -void foo7 (void) PLACE_IN_TCB("bar3"); -void foo8 (void) PLACE_IN_TCB("bar") PLACE_IN_TCB("bar2"); -void foo9 (void); - -void foo1() { - foo2(); // OK - function in same TCB - foo3(); // expected-warning {{calling 'foo3' is a violation of trusted computing base 'bar'}} - foo4(); // expected-warning {{calling 'foo4' is a violation of trusted computing base 'bar'}} - foo5(); // OK - in leaf node - foo6(); // OK - in multiple TCBs, one of which is the same - foo7(); // expected-warning {{calling 'foo7' is a violation of trusted computing base 'bar'}} - (void) __builtin_clz(5); // OK - builtins are excluded -} - -// Normal use without any attributes works -void foo3() { - foo9(); // no-warning -} - -void foo5() { - // all calls should be okay, function in TCB leaf - foo2(); // no-warning - foo3(); // no-warning - foo4(); // no-warning -} - -void foo6() { - foo1(); // expected-warning {{calling 'foo1' is a violation of trusted computing base 'bar2'}} - foo4(); // expected-warning {{calling 'foo4' is a violation of trusted computing base 'bar'}} - foo8(); // no-warning - foo7(); // #1 - // expected-warning@#1 {{calling 'foo7' is a violation of trusted computing base 'bar2'}} - // expected-warning@#1 {{calling 'foo7' is a violation of trusted computing base 'bar'}} -} - -// Ensure that attribute merging works as expected across redeclarations. -void foo10() PLACE_IN_TCB("bar"); -void foo10() PLACE_IN_TCB("bar2"); -void foo10() PLACE_IN_TCB("bar3"); -void foo10() { - foo1(); // #2 - // expected-warning@#2 {{calling 'foo1' is a violation of trusted computing base 'bar2'}} - // expected-warning@#2 {{calling 'foo1' is a violation of trusted computing base 'bar3'}} - foo3(); // #3 - // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar'}} - // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar2'}} - // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar3'}} - foo4(); // #4 - // expected-warning@#4 {{calling 'foo4' is a violation of trusted computing base 'bar'}} - // expected-warning@#4 {{calling 'foo4' is a violation of trusted computing base 'bar3'}} - foo7(); // #5 - // expected-warning@#5 {{calling 'foo7' is a violation of trusted computing base 'bar'}} - // expected-warning@#5 {{calling 'foo7' is a violation of trusted computing base 'bar2'}} -} diff --git a/clang/test/Sema/attr-enforce-tcb.cpp b/clang/test/Sema/attr-enforce-tcb.cpp deleted file mode 100644 index a01a1775e94b..000000000000 --- a/clang/test/Sema/attr-enforce-tcb.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#define PLACE_IN_TCB(NAME) [[clang::enforce_tcb(NAME)]] -#define PLACE_IN_TCB_LEAF(NAME) [[clang::enforce_tcb_leaf(NAME)]] - -PLACE_IN_TCB("foo") void in_tcb_foo(); -void not_in_tcb(); - -// Test behavior on classes and methods. -class C { - void bar(); - - PLACE_IN_TCB("foo") - void foo() { - // TODO: Figure out if we want to support methods at all. - // Does it even make sense to isolate individual methods into a TCB? - // Maybe a per-class attribute would make more sense? - bar(); // expected-warning{{calling 'bar' is a violation of trusted computing base 'foo'}} - } -}; - -// Test behavior on templates. -template <typename Ty> -PLACE_IN_TCB("foo") -void foo_never_instantiated() { - not_in_tcb(); // expected-warning{{calling 'not_in_tcb' is a violation of trusted computing base 'foo'}} - in_tcb_foo(); // no-warning -} - -template <typename Ty> -PLACE_IN_TCB("foo") -void foo_specialized(); - -template<> -void foo_specialized<int>() { - not_in_tcb(); // expected-warning{{calling 'not_in_tcb' is a violation of trusted computing base 'foo'}} - in_tcb_foo(); // no-warning -} - -PLACE_IN_TCB("foo") -void call_template_good() { - foo_specialized<int>(); // no-warning -} -PLACE_IN_TCB("bar") -void call_template_bad() { - foo_specialized<int>(); // expected-warning{{calling 'foo_specialized<int>' is a violation of trusted computing base 'bar'}} -} - -template<typename Ty> -void foo_specialization_in_tcb(); - -template<> -PLACE_IN_TCB("foo") -void foo_specialization_in_tcb<int>() { - not_in_tcb(); //expected-warning{{calling 'not_in_tcb' is a violation of trusted computing base 'foo'}} - in_tcb_foo(); // no-warning -} - -template<> -void foo_specialization_in_tcb<double>() { - not_in_tcb(); // no-warning - in_tcb_foo(); // no-warning -} - -PLACE_IN_TCB("foo") -void call_specialization_in_tcb() { - foo_specialization_in_tcb<int>(); // no-warning - foo_specialization_in_tcb<long>(); // expected-warning{{calling 'foo_specialization_in_tcb<long>' is a violation of trusted computing base 'foo'}} - foo_specialization_in_tcb<double>(); // expected-warning{{'foo_specialization_in_tcb<double>' is a violation of trusted computing base 'foo'}} -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits