nickdesaulniers created this revision. nickdesaulniers added reviewers: aaron.ballman, rsmith, erichkeane. Herald added a project: clang. Herald added a subscriber: cfe-commits.
r369705 did not consider the addition of gnu_inline on function declarations of alias attributed functions. This resulted in a reported regression in the clang-9-rc4 release from the Zig developers building glibc, which was observable as a failed assertion: llvm-project/clang/lib/AST/Decl.cpp:3336: bool clang::FunctionDecl::isInlineDefinitionExternallyVisible() const: Assertion `(doesThisDeclarationHaveABody() || willHaveBody()) && "Must be a function definition"' failed. Alias function declarations do not have bodies, so allow us to proceed if we have the alias function attribute but no body/definition, and add a test case. The emitted symbols and their linkage matches GCC for the added test case. Link: https://bugs.llvm.org/show_bug.cgi?id=43268 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D67455 Files: clang/lib/AST/Decl.cpp clang/test/CodeGen/alias.c Index: clang/test/CodeGen/alias.c =================================================================== --- clang/test/CodeGen/alias.c +++ clang/test/CodeGen/alias.c @@ -99,3 +99,8 @@ // CHECKGLOBALS-NOT: @test11_foo = dso_local void test11(void) {} static void test11_foo(void) __attribute__((alias("test11"))); + +// Test that gnu_inline+alias work. +// CHECKGLOBALS: @test12_alias = alias void (), void ()* @test12 +void test12(void) {} +inline void test12_alias(void) __attribute__((gnu_inline, alias("test12"))); Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -3348,8 +3348,8 @@ /// an externally visible symbol, but "extern inline" will not create an /// externally visible symbol. bool FunctionDecl::isInlineDefinitionExternallyVisible() const { - assert((doesThisDeclarationHaveABody() || willHaveBody()) && - "Must be a function definition"); + assert((doesThisDeclarationHaveABody() || willHaveBody()) || + hasAttr<AliasAttr>() && "Must be a function definition"); assert(isInlined() && "Function must be inline"); ASTContext &Context = getASTContext();
Index: clang/test/CodeGen/alias.c =================================================================== --- clang/test/CodeGen/alias.c +++ clang/test/CodeGen/alias.c @@ -99,3 +99,8 @@ // CHECKGLOBALS-NOT: @test11_foo = dso_local void test11(void) {} static void test11_foo(void) __attribute__((alias("test11"))); + +// Test that gnu_inline+alias work. +// CHECKGLOBALS: @test12_alias = alias void (), void ()* @test12 +void test12(void) {} +inline void test12_alias(void) __attribute__((gnu_inline, alias("test12"))); Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -3348,8 +3348,8 @@ /// an externally visible symbol, but "extern inline" will not create an /// externally visible symbol. bool FunctionDecl::isInlineDefinitionExternallyVisible() const { - assert((doesThisDeclarationHaveABody() || willHaveBody()) && - "Must be a function definition"); + assert((doesThisDeclarationHaveABody() || willHaveBody()) || + hasAttr<AliasAttr>() && "Must be a function definition"); assert(isInlined() && "Function must be inline"); ASTContext &Context = getASTContext();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits