Skip to content

Commit adf8453

Browse files
tambrytstellar
authored andcommitted
[Sema] Introduce BuiltinAttr, per-declaration builtin-ness
Instead of relying on whether a certain identifier is a builtin, introduce BuiltinAttr to specify a declaration as having builtin semantics. This fixes incompatible redeclarations of builtins, as reverting the identifier as being builtin due to one incompatible redeclaration would have broken rest of the builtin calls. Mostly-compatible redeclarations of builtins also no longer have builtin semantics. They don't call the builtin nor inherit their attributes. A long-standing FIXME regarding builtins inside a namespace enclosed in extern "C" not being recognized is also addressed. Due to the more correct handling attributes for builtin functions are added in more places, resulting in more useful warnings. Tests are updated to reflect that. Intrinsics without an inline definition in intrin.h had `inline` and `static` removed as they had no effect and caused them to no longer be recognized as builtins otherwise. A pthread_create() related test is XFAIL-ed, as it relied on it being recognized as a builtin based on its name. The builtin declaration syntax is too restrictive and doesn't allow custom structs, function pointers, etc. It seems to be the only case and fixing this would require reworking the current builtin syntax, so this seems acceptable. Fixes PR45410. Reviewed By: rsmith, yutsumi Differential Revision: https://reviews.llvm.org/D77491
1 parent 200eb1a commit adf8453

19 files changed

+193
-216
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,3 +3444,11 @@ def ReleaseHandle : InheritableParamAttr {
34443444
let Subjects = SubjectList<[ParmVar]>;
34453445
let Documentation = [ReleaseHandleDocs];
34463446
}
3447+
3448+
def Builtin : InheritableAttr {
3449+
let Spellings = [];
3450+
let Args = [UnsignedArgument<"ID">];
3451+
let Subjects = SubjectList<[Function]>;
3452+
let SemaHandler = 0;
3453+
let Documentation = [Undocumented];
3454+
}

clang/include/clang/Basic/Builtins.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
10171017
LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES)
10181018
LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES)
10191019
// POSIX pthread.h
1020+
// FIXME: Should specify argument types.
10201021
LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES)
10211022

10221023
// POSIX setjmp.h

clang/include/clang/Basic/IdentifierTable.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -225,18 +225,6 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
225225
}
226226
void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
227227

228-
/// True if setNotBuiltin() was called.
229-
bool hasRevertedBuiltin() const {
230-
return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS;
231-
}
232-
233-
/// Revert the identifier to a non-builtin identifier. We do this if
234-
/// the name of a known builtin library function is used to declare that
235-
/// function, but an unexpected type is specified.
236-
void revertBuiltin() {
237-
setBuiltinID(0);
238-
}
239-
240228
/// Return a value indicating whether this is a builtin function.
241229
///
242230
/// 0 is not-built-in. 1+ are specific builtin functions.

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3957,6 +3957,8 @@ class Sema final {
39573957
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
39583958
SourceLocation IdLoc,
39593959
bool TypoCorrection = false);
3960+
FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID,
3961+
SourceLocation Loc);
39603962
NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
39613963
Scope *S, bool ForRedeclaration,
39623964
SourceLocation Loc);

clang/lib/AST/Decl.cpp

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,44 +3162,24 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
31623162
/// functions as their wrapped builtins. This shouldn't be done in general, but
31633163
/// it's useful in Sema to diagnose calls to wrappers based on their semantics.
31643164
unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
3165-
unsigned BuiltinID;
3165+
unsigned BuiltinID = 0;
31663166

31673167
if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) {
31683168
BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
3169-
} else {
3170-
if (!getIdentifier())
3171-
return 0;
3172-
3173-
BuiltinID = getIdentifier()->getBuiltinID();
3169+
} else if (const auto *A = getAttr<BuiltinAttr>()) {
3170+
BuiltinID = A->getID();
31743171
}
31753172

31763173
if (!BuiltinID)
31773174
return 0;
31783175

3179-
ASTContext &Context = getASTContext();
3180-
if (Context.getLangOpts().CPlusPlus) {
3181-
const auto *LinkageDecl =
3182-
dyn_cast<LinkageSpecDecl>(getFirstDecl()->getDeclContext());
3183-
// In C++, the first declaration of a builtin is always inside an implicit
3184-
// extern "C".
3185-
// FIXME: A recognised library function may not be directly in an extern "C"
3186-
// declaration, for instance "extern "C" { namespace std { decl } }".
3187-
if (!LinkageDecl) {
3188-
if (BuiltinID == Builtin::BI__GetExceptionInfo &&
3189-
Context.getTargetInfo().getCXXABI().isMicrosoft())
3190-
return Builtin::BI__GetExceptionInfo;
3191-
return 0;
3192-
}
3193-
if (LinkageDecl->getLanguage() != LinkageSpecDecl::lang_c)
3194-
return 0;
3195-
}
3196-
31973176
// If the function is marked "overloadable", it has a different mangled name
31983177
// and is not the C library function.
31993178
if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() &&
32003179
!hasAttr<ArmBuiltinAliasAttr>())
32013180
return 0;
32023181

3182+
ASTContext &Context = getASTContext();
32033183
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
32043184
return BuiltinID;
32053185

0 commit comments

Comments
 (0)