diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -3892,7 +3892,10 @@ } Qualifiers getFastTypeQuals() const { - return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); + if (isFunctionProtoType()) + return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); + + return Qualifiers(); } public: diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp --- a/clang/unittests/AST/DeclTest.cpp +++ b/clang/unittests/AST/DeclTest.cpp @@ -354,3 +354,25 @@ EXPECT_TRUE(getFooValue->isInlined()); } + +TEST(Decl, NoProtoFunctionDeclAttributes) { + llvm::Annotations Code(R"( + void f(); + )"); + + auto AST = tooling::buildASTFromCodeWithArgs( + Code.code(), + /*Args=*/{"-target", "i386-apple-darwin", "-x", "objective-c", + "-std=c89"}); + ASTContext &Ctx = AST->getASTContext(); + + auto *f = selectFirst( + "f", match(functionDecl(hasName("f")).bind("f"), Ctx)); + + const auto *FPT = f->getType()->getAs(); + + // Functions without prototypes always have 0 initialized qualifiers + EXPECT_FALSE(FPT->isConst()); + EXPECT_FALSE(FPT->isVolatile()); + EXPECT_FALSE(FPT->isRestrict()); +}