Ignoring "slave lost exception" bots are green for a while http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast?numbuilds=100 http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap?numbuilds=100
Vlads report was done when bots were on staging master :8014 for github migration. Now they are on primary master :8011, so old links are stale. On Tue, Oct 29, 2019 at 5:33 AM Guillaume Chatelet via cfe-commits < cfe-commits@lists.llvm.org> wrote: > hi Vlad, > > I've spend a big part of my day digging into this and I'm less and less > convinced that my patch broke the builds. > IIUC the built bots are still failing although my patch has been > reverted for quite some time now. > > Am I missing something? > > On Mon, Oct 28, 2019 at 11:24 PM Vlad Tsyrklevich <v...@tsyrklevich.net> > wrote: > >> I've reverted this change as it was causing ASan/MSan failures in >> check-clang, e.g. take a look at the bottom 2 failures here: >> http://lab.llvm.org:8014/builders/sanitizer-x86_64-linux-bootstrap/builds/124/steps/check-clang%20asan/logs/stdio >> or >> here >> http://lab.llvm.org:8014/builders/sanitizer-x86_64-linux-fast/builds/126/steps/check-clang%20msan/logs/stdio >> >> On Mon, Oct 28, 2019 at 9:30 AM Guillaume Chatelet via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> >>> Author: Guillaume Chatelet >>> Date: 2019-10-28T17:30:11+01:00 >>> New Revision: bd87916109483d33455cbf20da2309197b983cdd >>> >>> URL: >>> https://github.com/llvm/llvm-project/commit/bd87916109483d33455cbf20da2309197b983cdd >>> DIFF: >>> https://github.com/llvm/llvm-project/commit/bd87916109483d33455cbf20da2309197b983cdd.diff >>> >>> LOG: [clang] Add no_builtin attribute >>> >>> Summary: >>> This is a follow up on https://reviews.llvm.org/D61634 >>> This patch is simpler and only adds the no_builtin attribute. >>> >>> Reviewers: tejohnson, courbet, theraven, t.p.northover, jdoerfert >>> >>> Subscribers: mgrang, cfe-commits >>> >>> Tags: #clang >>> >>> Differential Revision: https://reviews.llvm.org/D68028 >>> >>> Added: >>> clang/test/CodeGen/no-builtin.cpp >>> clang/test/Sema/no-builtin.cpp >>> >>> Modified: >>> clang/include/clang/AST/Decl.h >>> clang/include/clang/Basic/Attr.td >>> clang/include/clang/Basic/AttrDocs.td >>> clang/include/clang/Basic/DiagnosticSemaKinds.td >>> clang/lib/CodeGen/CGCall.cpp >>> clang/lib/Sema/SemaDecl.cpp >>> clang/lib/Sema/SemaDeclAttr.cpp >>> clang/test/Misc/pragma-attribute-supported-attributes-list.test >>> >>> Removed: >>> >>> >>> >>> >>> ################################################################################ >>> diff --git a/clang/include/clang/AST/Decl.h >>> b/clang/include/clang/AST/Decl.h >>> index b3e7a570fd6d..16094c0988fa 100644 >>> --- a/clang/include/clang/AST/Decl.h >>> +++ b/clang/include/clang/AST/Decl.h >>> @@ -2031,6 +2031,10 @@ class FunctionDecl : public DeclaratorDecl, >>> /// >>> /// This does not determine whether the function has been defined >>> (e.g., in a >>> /// previous definition); for that information, use isDefined. >>> + /// >>> + /// Note: the function declaration does not become a definition until >>> the >>> + /// parser reaches the definition, if called before, this function >>> will return >>> + /// `false`. >>> bool isThisDeclarationADefinition() const { >>> return isDeletedAsWritten() || isDefaulted() || Body || >>> hasSkippedBody() || >>> isLateTemplateParsed() || willHaveBody() || >>> hasDefiningAttr(); >>> >>> diff --git a/clang/include/clang/Basic/Attr.td >>> b/clang/include/clang/Basic/Attr.td >>> index 4557a614d361..d5018f444e1c 100644 >>> --- a/clang/include/clang/Basic/Attr.td >>> +++ b/clang/include/clang/Basic/Attr.td >>> @@ -3427,3 +3427,10 @@ def ObjCExternallyRetained : InheritableAttr { >>> let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>; >>> let Documentation = [ObjCExternallyRetainedDocs]; >>> } >>> + >>> +def NoBuiltin : Attr { >>> + let Spellings = [Clang<"no_builtin">]; >>> + let Args = [VariadicStringArgument<"BuiltinNames">]; >>> + let Subjects = SubjectList<[Function]>; >>> + let Documentation = [NoBuiltinDocs]; >>> +} >>> >>> diff --git a/clang/include/clang/Basic/AttrDocs.td >>> b/clang/include/clang/Basic/AttrDocs.td >>> index 6e79d0bb3631..9d0d27407573 100644 >>> --- a/clang/include/clang/Basic/AttrDocs.td >>> +++ b/clang/include/clang/Basic/AttrDocs.td >>> @@ -4413,3 +4413,40 @@ and is not a general mechanism for declaring >>> arbitrary aliases for >>> clang builtin functions. >>> }]; >>> } >>> + >>> +def NoBuiltinDocs : Documentation { >>> + let Category = DocCatFunction; >>> + let Content = [{ >>> +.. Note:: This attribute is not yet fully implemented, it is validated >>> but has >>> +no effect on the generated code. >>> + >>> +The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` >>> flag >>> +except it is specific to the body of a function. The attribute may also >>> be >>> +applied to a virtual function but has no effect on the behavior of >>> overriding >>> +functions in a derived class. >>> + >>> +It accepts one or more strings corresponding to the specific names of >>> the >>> +builtins to disable (e.g. "memcpy", "memset"). >>> +If the attribute is used without parameters it will disable all buitins >>> at >>> +once. >>> + >>> +.. code-block:: c++ >>> + >>> + // The compiler is not allowed to add any builtin to foo's body. >>> + void foo(char* data, size_t count) __attribute__((no_builtin)) { >>> + // The compiler is not allowed to convert the loop into >>> + // `__builtin_memset(data, 0xFE, count);`. >>> + for (size_t i = 0; i < count; ++i) >>> + data[i] = 0xFE; >>> + } >>> + >>> + // The compiler is not allowed to add the `memcpy` builtin to bar's >>> body. >>> + void bar(char* data, size_t count) >>> __attribute__((no_builtin("memcpy"))) { >>> + // The compiler is allowed to convert the loop into >>> + // `__builtin_memset(data, 0xFE, count);` but cannot generate any >>> + // `__builtin_memcpy` >>> + for (size_t i = 0; i < count; ++i) >>> + data[i] = 0xFE; >>> + } >>> + }]; >>> +} >>> >>> diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td >>> b/clang/include/clang/Basic/DiagnosticSemaKinds.td >>> index db877a46c300..20670a98fe03 100644 >>> --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td >>> +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td >>> @@ -3624,6 +3624,15 @@ def err_attribute_overloadable_no_prototype : >>> Error< >>> def err_attribute_overloadable_multiple_unmarked_overloads : Error< >>> "at most one overload for a given name may lack the 'overloadable' " >>> "attribute">; >>> +def warn_attribute_no_builtin_invalid_builtin_name : Warning< >>> + "'%0' is not a valid builtin name for %1">, >>> + InGroup<DiagGroup<"invalid-no-builtin-names">>; >>> +def err_attribute_no_builtin_wildcard_or_builtin_name : Error< >>> + "empty %0 cannot be composed with named ones">; >>> +def err_attribute_no_builtin_on_non_definition : Error< >>> + "%0 attribute is permitted on definitions only">; >>> +def err_attribute_no_builtin_on_defaulted_deleted_function : Error< >>> + "%0 attribute has no effect on defaulted or deleted functions">; >>> def warn_ns_attribute_wrong_return_type : Warning< >>> "%0 attribute only applies to %select{functions|methods|properties}1 >>> that " >>> "return %select{an Objective-C object|a pointer|a non-retainable >>> pointer}2">, >>> >>> diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp >>> index b74f6f942426..62e8fa037013 100644 >>> --- a/clang/lib/CodeGen/CGCall.cpp >>> +++ b/clang/lib/CodeGen/CGCall.cpp >>> @@ -1853,11 +1853,27 @@ void CodeGenModule::ConstructAttributeList( >>> if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { >>> AddAttributesFromFunctionProtoType( >>> getContext(), FuncAttrs, >>> Fn->getType()->getAs<FunctionProtoType>()); >>> - // Don't use [[noreturn]] or _Noreturn for a call to a virtual >>> function. >>> - // These attributes are not inherited by overloads. >>> const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn); >>> - if (Fn->isNoReturn() && !(AttrOnCallSite && MD && >>> MD->isVirtual())) >>> - FuncAttrs.addAttribute(llvm::Attribute::NoReturn); >>> + const bool IsVirtualCall = MD && MD->isVirtual(); >>> + // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call >>> to a >>> + // virtual function. These attributes are not inherited by >>> overloads. >>> + if (!(AttrOnCallSite && IsVirtualCall)) { >>> + if (Fn->isNoReturn()) >>> + FuncAttrs.addAttribute(llvm::Attribute::NoReturn); >>> + >>> + if (const auto *NBA = TargetDecl->getAttr<NoBuiltinAttr>()) { >>> + bool HasWildcard = llvm::is_contained(NBA->builtinNames(), >>> "*"); >>> + if (HasWildcard) >>> + FuncAttrs.addAttribute("no-builtins"); >>> + else >>> + for (StringRef BuiltinName : NBA->builtinNames()) { >>> + SmallString<32> AttributeName; >>> + AttributeName += "no-builtin-"; >>> + AttributeName += BuiltinName; >>> + FuncAttrs.addAttribute(AttributeName); >>> + } >>> + } >>> + } >>> } >>> >>> // 'const', 'pure' and 'noalias' attributed functions are also >>> nounwind. >>> >>> diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp >>> index 6202391ee0b8..aba7049b0a51 100644 >>> --- a/clang/lib/Sema/SemaDecl.cpp >>> +++ b/clang/lib/Sema/SemaDecl.cpp >>> @@ -9529,6 +9529,29 @@ Sema::ActOnFunctionDeclarator(Scope *S, >>> Declarator &D, DeclContext *DC, >>> } >>> } >>> >>> + // Diagnose no_builtin attribute on function declaration that are not >>> a >>> + // definition. >>> + // FIXME: We should really be doing this in >>> + // SemaDeclAttr.cpp::handleNoBuiltinAttr, unfortunately we only have >>> access to >>> + // the FunctionDecl and at this point of the code >>> + // FunctionDecl::isThisDeclarationADefinition() which always returns >>> `false` >>> + // because Sema::ActOnStartOfFunctionDef has not been called yet. >>> + if (const auto *NBA = NewFD->getAttr<NoBuiltinAttr>()) >>> + switch (D.getFunctionDefinitionKind()) { >>> + case FDK_Defaulted: >>> + case FDK_Deleted: >>> + Diag(NBA->getLocation(), >>> + diag::err_attribute_no_builtin_on_defaulted_deleted_function) >>> + << NBA->getSpelling(); >>> + break; >>> + case FDK_Declaration: >>> + Diag(NBA->getLocation(), >>> diag::err_attribute_no_builtin_on_non_definition) >>> + << NBA->getSpelling(); >>> + break; >>> + case FDK_Definition: >>> + break; >>> + } >>> + >>> return NewFD; >>> } >>> >>> >>> diff --git a/clang/lib/Sema/SemaDeclAttr.cpp >>> b/clang/lib/Sema/SemaDeclAttr.cpp >>> index abbd597a26d0..99eb23c3fe61 100644 >>> --- a/clang/lib/Sema/SemaDeclAttr.cpp >>> +++ b/clang/lib/Sema/SemaDeclAttr.cpp >>> @@ -1069,6 +1069,56 @@ static void handleDiagnoseIfAttr(Sema &S, Decl >>> *D, const ParsedAttr &AL) { >>> S.Context, AL, Cond, Msg, DiagType, ArgDependent, >>> cast<NamedDecl>(D))); >>> } >>> >>> +static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) >>> { >>> + static constexpr const StringRef kWildcard = "*"; >>> + >>> + llvm::SmallVector<StringRef, 16> Names; >>> + bool HasWildcard = false; >>> + >>> + const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) { >>> + if (Name == kWildcard) >>> + HasWildcard = true; >>> + Names.push_back(Name); >>> + }; >>> + >>> + // Add previously defined attributes. >>> + if (const auto *NBA = D->getAttr<NoBuiltinAttr>()) >>> + for (StringRef BuiltinName : NBA->builtinNames()) >>> + AddBuiltinName(BuiltinName); >>> + >>> + // Add current attributes. >>> + if (AL.getNumArgs() == 0) >>> + AddBuiltinName(kWildcard); >>> + else >>> + for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) { >>> + StringRef BuiltinName; >>> + SourceLocation LiteralLoc; >>> + if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, >>> &LiteralLoc)) >>> + return; >>> + >>> + if (Builtin::Context::isBuiltinFunc(BuiltinName.data())) >>> + AddBuiltinName(BuiltinName); >>> + else >>> + S.Diag(LiteralLoc, >>> diag::warn_attribute_no_builtin_invalid_builtin_name) >>> + << BuiltinName << AL.getAttrName()->getName(); >>> + } >>> + >>> + // Repeating the same attribute is fine. >>> + llvm::sort(Names); >>> + Names.erase(std::unique(Names.begin(), Names.end()), Names.end()); >>> + >>> + // Empty no_builtin must be on its own. >>> + if (HasWildcard && Names.size() > 1) >>> + S.Diag(D->getLocation(), >>> + diag::err_attribute_no_builtin_wildcard_or_builtin_name) >>> + << AL.getAttrName()->getName(); >>> + >>> + if (D->hasAttr<NoBuiltinAttr>()) >>> + D->dropAttr<NoBuiltinAttr>(); >>> + D->addAttr(::new (S.Context) >>> + NoBuiltinAttr(S.Context, AL, Names.data(), >>> Names.size())); >>> +} >>> + >>> static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr >>> &AL) { >>> if (D->hasAttr<PassObjectSizeAttr>()) { >>> S.Diag(D->getBeginLoc(), >>> diag::err_attribute_only_once_per_parameter) << AL; >>> @@ -6608,6 +6658,9 @@ static void ProcessDeclAttribute(Sema &S, Scope >>> *scope, Decl *D, >>> case ParsedAttr::AT_DiagnoseIf: >>> handleDiagnoseIfAttr(S, D, AL); >>> break; >>> + case ParsedAttr::AT_NoBuiltin: >>> + handleNoBuiltinAttr(S, D, AL); >>> + break; >>> case ParsedAttr::AT_ExtVectorType: >>> handleExtVectorTypeAttr(S, D, AL); >>> break; >>> >>> diff --git a/clang/test/CodeGen/no-builtin.cpp >>> b/clang/test/CodeGen/no-builtin.cpp >>> new file mode 100644 >>> index 000000000000..3c5d681282da >>> --- /dev/null >>> +++ b/clang/test/CodeGen/no-builtin.cpp >>> @@ -0,0 +1,64 @@ >>> +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - %s | >>> FileCheck %s >>> + >>> +// CHECK-LABEL: define void @foo_no_mempcy() #0 >>> +extern "C" void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {} >>> + >>> +// CHECK-LABEL: define void @foo_no_mempcy_twice() #0 >>> +extern "C" void foo_no_mempcy_twice() >>> __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcpy"))) >>> {} >>> + >>> +// CHECK-LABEL: define void @foo_no_builtins() #1 >>> +extern "C" void foo_no_builtins() __attribute__((no_builtin)) {} >>> + >>> +// CHECK-LABEL: define void @foo_no_mempcy_memset() #2 >>> +extern "C" void foo_no_mempcy_memset() >>> __attribute__((no_builtin("memset", "memcpy"))) {} >>> + >>> +// CHECK-LABEL: define void @separate_attrs() #2 >>> +extern "C" void separate_attrs() __attribute__((no_builtin("memset"))) >>> __attribute__((no_builtin("memcpy"))) {} >>> + >>> +// CHECK-LABEL: define void @separate_attrs_ordering() #2 >>> +extern "C" void separate_attrs_ordering() >>> __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memset"))) >>> {} >>> + >>> +struct A { >>> + virtual int foo() const __attribute__((no_builtin("memcpy"))) { >>> return 1; } >>> + virtual ~A(); >>> +}; >>> + >>> +struct B : public A { >>> + int foo() const override __attribute__((no_builtin("memmove"))) { >>> return 2; } >>> + virtual ~B(); >>> +}; >>> + >>> +// CHECK-LABEL: define void @call_a_foo(%struct.A* %a) #3 >>> +extern "C" void call_a_foo(A *a) { >>> + // CHECK: %call = call i32 %2(%struct.A* %0) >>> + a->foo(); // virtual call is not annotated >>> +} >>> + >>> +// CHECK-LABEL: define void @call_b_foo(%struct.B* %b) #3 >>> +extern "C" void call_b_foo(B *b) { >>> + // CHECK: %call = call i32 %2(%struct.B* %0) >>> + b->foo(); // virtual call is not annotated >>> +} >>> + >>> +// CHECK-LABEL: define void @call_foo_no_mempcy() #3 >>> +extern "C" void call_foo_no_mempcy() { >>> + // CHECK: call void @foo_no_mempcy() #6 >>> + foo_no_mempcy(); // call gets annotated with "no-builtin-memcpy" >>> +} >>> + >>> +A::~A() {} // Anchoring A so A::foo() gets generated >>> +B::~B() {} // Anchoring B so B::foo() gets generated >>> + >>> +// CHECK-LABEL: define linkonce_odr i32 @_ZNK1A3fooEv(%struct.A* %this) >>> unnamed_addr #0 comdat align 2 >>> +// CHECK-LABEL: define linkonce_odr i32 @_ZNK1B3fooEv(%struct.B* %this) >>> unnamed_addr #5 comdat align 2 >>> + >>> +// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}} >>> +// CHECK-NOT: attributes #0 = {{{.*}}"no-builtin-memmove"{{.*}}} >>> +// CHECK-NOT: attributes #0 = {{{.*}}"no-builtin-memset"{{.*}}} >>> +// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}} >>> +// CHECK: attributes #2 = >>> {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}} >>> +// CHECK-NOT: attributes #2 = {{{.*}}"no-builtin-memmove"{{.*}}} >>> +// CHECK: attributes #5 = {{{.*}}"no-builtin-memmove"{{.*}}} >>> +// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memcpy"{{.*}}} >>> +// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memset"{{.*}}} >>> +// CHECK: attributes #6 = { "no-builtin-memcpy" } >>> >>> diff --git >>> a/clang/test/Misc/pragma-attribute-supported-attributes-list.test >>> b/clang/test/Misc/pragma-attribute-supported-attributes-list.test >>> index 25802bd73c51..729e9b7a6f77 100644 >>> --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test >>> +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test >>> @@ -75,6 +75,7 @@ >>> // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter) >>> // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method) >>> // CHECK-NEXT: Naked (SubjectMatchRule_function) >>> +// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function) >>> // CHECK-NEXT: NoCommon (SubjectMatchRule_variable) >>> // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, >>> SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, >>> SubjectMatchRule_variable_not_is_parameter) >>> // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable) >>> >>> diff --git a/clang/test/Sema/no-builtin.cpp >>> b/clang/test/Sema/no-builtin.cpp >>> new file mode 100644 >>> index 000000000000..40781abd3037 >>> --- /dev/null >>> +++ b/clang/test/Sema/no-builtin.cpp >>> @@ -0,0 +1,51 @@ >>> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify >>> %s >>> + >>> +/// Prevent use of all builtins. >>> +void valid_attribute_all_1() __attribute__((no_builtin)) {} >>> +void valid_attribute_all_2() __attribute__((no_builtin())) {} >>> + >>> +/// Prevent use of specific builtins. >>> +void valid_attribute_function() __attribute__((no_builtin("memcpy"))) {} >>> +void valid_attribute_functions() __attribute__((no_builtin("memcpy"))) >>> __attribute__((no_builtin("memcmp"))) {} >>> + >>> +/// Many times the same builtin is fine. >>> +void many_attribute_function_1() __attribute__((no_builtin)) >>> __attribute__((no_builtin)) {} >>> +void many_attribute_function_2() __attribute__((no_builtin("memcpy"))) >>> __attribute__((no_builtin("memcpy"))) {} >>> +void many_attribute_function_3() __attribute__((no_builtin("memcpy", >>> "memcpy"))) {} >>> +void many_attribute_function_4() __attribute__((no_builtin("memcpy", >>> "memcpy"))) __attribute__((no_builtin("memcpy"))) {} >>> + >>> +/// Invalid builtin name. >>> +void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {} >>> +// expected-warning@-1 {{'not_a_builtin' is not a valid builtin name >>> for no_builtin}} >>> + >>> +/// Can't use bare no_builtin with a named one. >>> +void wildcard_and_functionname() __attribute__((no_builtin)) >>> __attribute__((no_builtin("memcpy"))) {} >>> +// expected-error@-1 {{empty no_builtin cannot be composed with named >>> ones}} >>> + >>> +/// Can't attach attribute to a variable. >>> +int __attribute__((no_builtin)) variable; >>> +// expected-warning@-1 {{'no_builtin' attribute only applies to >>> functions}} >>> + >>> +/// Can't attach attribute to a declaration. >>> +void nobuiltin_on_declaration() __attribute__((no_builtin)); >>> +// expected-error@-1 {{no_builtin attribute is permitted on >>> definitions only}} >>> + >>> +struct S { >>> + /// Can't attach attribute to a defaulted function, >>> + S() >>> + __attribute__((no_builtin)) = default; >>> + // expected-error@-1 {{no_builtin attribute has no effect on >>> defaulted or deleted functions}} >>> + >>> + /// Can't attach attribute to a deleted function, >>> + S(const S &) >>> + __attribute__((no_builtin)) = delete; >>> + // expected-error@-1 {{no_builtin attribute has no effect on >>> defaulted or deleted functions}} >>> + >>> + void whatever() __attribute__((no_builtin("memcpy"))); >>> + // expected-error@-1 {{no_builtin attribute is permitted on >>> definitions only}} >>> +}; >>> + >>> +/// Can't attach attribute to an aliased function. >>> +void alised_function() {} >>> +void aliasing_function() __attribute__((no_builtin)) >>> __attribute__((alias("alised_function"))); >>> +// expected-error@-1 {{no_builtin attribute is permitted on >>> definitions only}} >>> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits