Index: clang/lib/Lex/PPMacroExpansion.cpp =================================================================== --- clang/lib/Lex/PPMacroExpansion.cpp +++ clang/lib/Lex/PPMacroExpansion.cpp @@ -1693,8 +1693,14 @@ [this](Token &Tok, bool &HasLexedNextToken) -> int { IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this, diag::err_feature_check_malformed); - return II ? hasAttribute(AttrSyntax::Declspec, nullptr, II, - getTargetInfo(), getLangOpts()) : 0; + if (II) { + const LangOptions &LangOpts = getLangOpts(); + return LangOpts.DeclSpecKeyword && + hasAttribute(AttrSyntax::Declspec, nullptr, II, + getTargetInfo(), LangOpts); + } + + return false; }); } else if (II == Ident__has_cpp_attribute || II == Ident__has_c_attribute) { Index: clang/test/Preprocessor/has_declspec_attribute.c =================================================================== --- /dev/null +++ clang/test/Preprocessor/has_declspec_attribute.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -E -P %s -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -triple i386-unknown-unknown -fdeclspec -E -P %s -o - | FileCheck %s --check-prefix=ENABLED +// RUN: %clang_cc1 -triple i386-unknown-unknown -fms-extensions -E -P %s -o - | FileCheck %s --check-prefix=ENABLED + +// Check that __has_declspec_attribute() always returns 0 if declspec +// attributes have not been explicitly enabled. + +#define DECLSPEC(x) x: __has_declspec_attribute(x) +// CHECK: noreturn: 0 +// ENABLED: noreturn: 1 +DECLSPEC(noreturn)