blob: 5de7a268600e57a5a5aa7d0525dde87abf5d9d8a [file] [log] [blame]
From c3cecb51bd66712f2a00a5d516061b372f7b7c06 Mon Sep 17 00:00:00 2001
From: Chih-Hung Hsieh <chh@google.com>
Date: Mon, 22 Feb 2021 15:40:47 -0800
Subject: [PATCH] Revert "[Sema] Introduce BuiltinAttr, per-declaration
builtin-ness"
This reverts commit e09107ab80dced55414fa458cf78e6cdfe90da6e.
Change-Id: Idc61b29dba6e2948cb2f62b78350dfbfb5c82cd6
---
clang/include/clang/Basic/Attr.td | 8 --
clang/include/clang/Basic/Builtins.def | 1 -
clang/include/clang/Basic/IdentifierTable.h | 12 ++
clang/include/clang/Sema/Sema.h | 2 -
clang/lib/AST/Decl.cpp | 29 ++++-
clang/lib/Headers/intrin.h | 118 ++++++++++-------
clang/lib/Sema/SemaDecl.cpp | 120 +++++++-----------
clang/lib/Sema/SemaExpr.cpp | 1 -
clang/lib/Sema/SemaLookup.cpp | 7 +-
clang/lib/Serialization/ASTReader.cpp | 12 +-
clang/lib/Serialization/ASTWriter.cpp | 6 +-
clang/test/AST/ast-dump-attr.cpp | 1 -
clang/test/CodeGen/builtin-redeclaration.c | 16 ---
clang/test/CodeGen/callback_pthread_create.c | 4 -
clang/test/CodeGenCXX/builtins.cpp | 14 --
clang/test/Sema/implicit-builtin-decl.c | 5 +
clang/test/Sema/warn-fortify-source.c | 19 ++-
clang/test/SemaCXX/cxx11-compat.cpp | 2 +-
.../SemaCXX/warn-unused-local-typedef.cpp | 4 +-
19 files changed, 200 insertions(+), 181 deletions(-)
delete mode 100644 clang/test/CodeGen/builtin-redeclaration.c
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 5bfcec732907..58666a5a7974 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3774,14 +3774,6 @@ def ReleaseHandle : InheritableParamAttr {
let Documentation = [ReleaseHandleDocs];
}
-def Builtin : InheritableAttr {
- let Spellings = [];
- let Args = [UnsignedArgument<"ID">];
- let Subjects = SubjectList<[Function]>;
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
def EnforceTCB : InheritableAttr {
let Spellings = [Clang<"enforce_tcb">];
let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 5a9d0a001829..88f80abe677c 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -1087,7 +1087,6 @@ LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(vfork, "p", "fjT", "unistd.h", ALL_LANGUAGES)
// POSIX pthread.h
-// FIXME: Should specify argument types.
LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES)
// POSIX setjmp.h
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index e074a7d3254c..3ea65ef65142 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -233,6 +233,18 @@ public:
}
void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
+ /// True if setNotBuiltin() was called.
+ bool hasRevertedBuiltin() const {
+ return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS;
+ }
+
+ /// Revert the identifier to a non-builtin identifier. We do this if
+ /// the name of a known builtin library function is used to declare that
+ /// function, but an unexpected type is specified.
+ void revertBuiltin() {
+ setBuiltinID(0);
+ }
+
/// Return a value indicating whether this is a builtin function.
///
/// 0 is not-built-in. 1+ are specific builtin functions.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 07518b37eb98..05d47fd2ab92 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4247,8 +4247,6 @@ public:
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
SourceLocation IdLoc,
bool TypoCorrection = false);
- FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID,
- SourceLocation Loc);
NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
Scope *S, bool ForRedeclaration,
SourceLocation Loc);
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c5c8f473dda9..3b7d6f3387bd 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3284,26 +3284,45 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
/// functions as their wrapped builtins. This shouldn't be done in general, but
/// it's useful in Sema to diagnose calls to wrappers based on their semantics.
unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
- unsigned BuiltinID = 0;
+ unsigned BuiltinID;
if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) {
BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
} else if (const auto *BAA = getAttr<BuiltinAliasAttr>()) {
BuiltinID = BAA->getBuiltinName()->getBuiltinID();
- } else if (const auto *A = getAttr<BuiltinAttr>()) {
- BuiltinID = A->getID();
- }
+ } else {
+ if (!getIdentifier())
+ return 0;
+ BuiltinID = getIdentifier()->getBuiltinID();
+ }
if (!BuiltinID)
return 0;
+ ASTContext &Context = getASTContext();
+ if (Context.getLangOpts().CPlusPlus) {
+ const auto *LinkageDecl =
+ dyn_cast<LinkageSpecDecl>(getFirstDecl()->getDeclContext());
+ // In C++, the first declaration of a builtin is always inside an implicit
+ // extern "C".
+ // FIXME: A recognised library function may not be directly in an extern "C"
+ // declaration, for instance "extern "C" { namespace std { decl } }".
+ if (!LinkageDecl) {
+ if (BuiltinID == Builtin::BI__GetExceptionInfo &&
+ Context.getTargetInfo().getCXXABI().isMicrosoft())
+ return Builtin::BI__GetExceptionInfo;
+ return 0;
+ }
+ if (LinkageDecl->getLanguage() != LinkageSpecDecl::lang_c)
+ return 0;
+ }
+
// If the function is marked "overloadable", it has a different mangled name
// and is not the C library function.
if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() &&
(!hasAttr<ArmBuiltinAliasAttr>() && !hasAttr<BuiltinAliasAttr>()))
return 0;
- ASTContext &Context = getASTContext();
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
return BuiltinID;
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 2b4e1b75e404..a42a1ee5e300 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -57,11 +57,16 @@ void __addfsbyte(unsigned long, unsigned char);
void __addfsdword(unsigned long, unsigned long);
void __addfsword(unsigned long, unsigned short);
void __code_seg(const char *);
+static __inline__
void __cpuid(int[4], int);
+static __inline__
void __cpuidex(int[4], int, int);
+static __inline__
__int64 __emul(int, int);
+static __inline__
unsigned __int64 __emulu(unsigned int, unsigned int);
unsigned int __getcallerseflags(void);
+static __inline__
void __halt(void);
unsigned char __inbyte(unsigned short);
void __inbytestring(unsigned short, unsigned char *, unsigned long);
@@ -77,9 +82,13 @@ void __inwordstring(unsigned short, unsigned short *, unsigned long);
void __lidt(void *);
unsigned __int64 __ll_lshift(unsigned __int64, int);
__int64 __ll_rshift(__int64, int);
+static __inline__
void __movsb(unsigned char *, unsigned char const *, size_t);
+static __inline__
void __movsd(unsigned long *, unsigned long const *, size_t);
+static __inline__
void __movsw(unsigned short *, unsigned short const *, size_t);
+static __inline__
void __nop(void);
void __nvreg_restore_fence(void);
void __nvreg_save_fence(void);
@@ -96,16 +105,23 @@ unsigned long __readcr4(void);
unsigned long __readcr8(void);
unsigned int __readdr(unsigned int);
#ifdef __i386__
+static __inline__
unsigned char __readfsbyte(unsigned long);
+static __inline__
unsigned __int64 __readfsqword(unsigned long);
+static __inline__
unsigned short __readfsword(unsigned long);
#endif
+static __inline__
unsigned __int64 __readmsr(unsigned long);
unsigned __int64 __readpmc(unsigned long);
unsigned long __segmentlimit(unsigned long);
void __sidt(void *);
+static __inline__
void __stosb(unsigned char *, unsigned char, size_t);
+static __inline__
void __stosd(unsigned long *, unsigned long, size_t);
+static __inline__
void __stosw(unsigned short *, unsigned short, size_t);
void __svm_clgi(void);
void __svm_invlpga(void *, int);
@@ -120,6 +136,7 @@ void __vmx_off(void);
void __vmx_vmptrst(unsigned __int64 *);
void __wbinvd(void);
void __writecr0(unsigned int);
+static __inline__
void __writecr3(unsigned __INTPTR_TYPE__);
void __writecr4(unsigned int);
void __writecr8(unsigned int);
@@ -129,8 +146,11 @@ void __writefsdword(unsigned long, unsigned long);
void __writefsqword(unsigned long, unsigned __int64);
void __writefsword(unsigned long, unsigned short);
void __writemsr(unsigned long, unsigned __int64);
+static __inline__
void *_AddressOfReturnAddress(void);
+static __inline__
unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
+static __inline__
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
unsigned char _bittest(long const *, long);
unsigned char _bittestandcomplement(long *, long);
@@ -149,10 +169,12 @@ long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
__int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
__int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
-void __attribute__((__deprecated__(
- "use other intrinsics or C++11 atomics instead"))) _ReadBarrier(void);
-void __attribute__((__deprecated__(
- "use other intrinsics or C++11 atomics instead"))) _ReadWriteBarrier(void);
+static __inline__ void
+__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
+_ReadBarrier(void);
+static __inline__ void
+__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
+_ReadWriteBarrier(void);
unsigned int _rorx_u32(unsigned int, const unsigned int);
int _sarx_i32(int, unsigned int);
#if __STDC_HOSTED__
@@ -163,8 +185,9 @@ unsigned int _shrx_u32(unsigned int, unsigned int);
void _Store_HLERelease(long volatile *, long);
void _Store64_HLERelease(__int64 volatile *, __int64);
void _StorePointer_HLERelease(void *volatile *, void *);
-void __attribute__((__deprecated__(
- "use other intrinsics or C++11 atomics instead"))) _WriteBarrier(void);
+static __inline__ void
+__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
+_WriteBarrier(void);
unsigned __int32 xbegin(void);
void _xend(void);
@@ -174,14 +197,19 @@ void __addgsbyte(unsigned long, unsigned char);
void __addgsdword(unsigned long, unsigned long);
void __addgsqword(unsigned long, unsigned __int64);
void __addgsword(unsigned long, unsigned short);
+static __inline__
void __faststorefence(void);
void __incgsbyte(unsigned long);
void __incgsdword(unsigned long);
void __incgsqword(unsigned long);
void __incgsword(unsigned long);
+static __inline__
void __movsq(unsigned long long *, unsigned long long const *, size_t);
+static __inline__
unsigned char __readgsbyte(unsigned long);
+static __inline__
unsigned long __readgsdword(unsigned long);
+static __inline__
unsigned __int64 __readgsqword(unsigned long);
unsigned short __readgsword(unsigned long);
unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
@@ -190,6 +218,7 @@ unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
unsigned __int64 __shiftright128(unsigned __int64 _LowPart,
unsigned __int64 _HighPart,
unsigned char _Shift);
+static __inline__
void __stosq(unsigned __int64 *, unsigned __int64, size_t);
unsigned char __vmx_on(unsigned __int64 *);
unsigned char __vmx_vmclear(unsigned __int64 *);
@@ -236,9 +265,13 @@ unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
__int64 _sarx_i64(__int64, unsigned int);
unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
unsigned __int64 _shrx_u64(unsigned __int64, unsigned int);
+static __inline__
__int64 __mulh(__int64, __int64);
+static __inline__
unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
+static __inline__
__int64 _mul128(__int64, __int64, __int64*);
+static __inline__
unsigned __int64 _umul128(unsigned __int64,
unsigned __int64,
unsigned __int64*);
@@ -247,19 +280,29 @@ unsigned __int64 _umul128(unsigned __int64,
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+static __inline__
unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
+static __inline__
unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
#endif
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+static __inline__
__int64 _InterlockedDecrement64(__int64 volatile *_Addend);
+static __inline__
__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
+static __inline__
__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
+static __inline__
__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value);
+static __inline__
__int64 _InterlockedIncrement64(__int64 volatile *_Addend);
+static __inline__
__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask);
+static __inline__
__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask);
+static __inline__
__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask);
#endif
@@ -448,56 +491,40 @@ unsigned char _InterlockedCompareExchange128_rel(__int64 volatile *_Destination,
|* movs, stos
\*----------------------------------------------------------------------------*/
#if defined(__i386__) || defined(__x86_64__)
-static __inline__ void __DEFAULT_FN_ATTRS __movsb(unsigned char *__dst,
- unsigned char const *__src,
- size_t __n) {
+static __inline__ void __DEFAULT_FN_ATTRS
+__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
__asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n)
: : "memory");
}
-static __inline__ void __DEFAULT_FN_ATTRS __movsd(unsigned long *__dst,
- unsigned long const *__src,
- size_t __n) {
- __asm__ __volatile__("rep movsl"
- : "+D"(__dst), "+S"(__src), "+c"(__n)
- :
- : "memory");
+static __inline__ void __DEFAULT_FN_ATTRS
+__movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
+ __asm__ __volatile__("rep movsl" : "+D"(__dst), "+S"(__src), "+c"(__n)
+ : : "memory");
}
-static __inline__ void __DEFAULT_FN_ATTRS __movsw(unsigned short *__dst,
- unsigned short const *__src,
- size_t __n) {
- __asm__ __volatile__("rep movsw"
- : "+D"(__dst), "+S"(__src), "+c"(__n)
- :
- : "memory");
+static __inline__ void __DEFAULT_FN_ATTRS
+__movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
+ __asm__ __volatile__("rep movsw" : "+D"(__dst), "+S"(__src), "+c"(__n)
+ : : "memory");
}
-static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst,
- unsigned long __x,
- size_t __n) {
- __asm__ __volatile__("rep stosl"
- : "+D"(__dst), "+c"(__n)
- : "a"(__x)
+static __inline__ void __DEFAULT_FN_ATTRS
+__stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
+ __asm__ __volatile__("rep stosl" : "+D"(__dst), "+c"(__n) : "a"(__x)
: "memory");
}
-static __inline__ void __DEFAULT_FN_ATTRS __stosw(unsigned short *__dst,
- unsigned short __x,
- size_t __n) {
- __asm__ __volatile__("rep stosw"
- : "+D"(__dst), "+c"(__n)
- : "a"(__x)
+static __inline__ void __DEFAULT_FN_ATTRS
+__stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
+ __asm__ __volatile__("rep stosw" : "+D"(__dst), "+c"(__n) : "a"(__x)
: "memory");
}
#endif
#ifdef __x86_64__
-static __inline__ void __DEFAULT_FN_ATTRS __movsq(
- unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
- __asm__ __volatile__("rep movsq"
- : "+D"(__dst), "+S"(__src), "+c"(__n)
- :
- : "memory");
+static __inline__ void __DEFAULT_FN_ATTRS
+__movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
+ __asm__ __volatile__("rep movsq" : "+D"(__dst), "+S"(__src), "+c"(__n)
+ : : "memory");
}
-static __inline__ void __DEFAULT_FN_ATTRS __stosq(unsigned __int64 *__dst,
- unsigned __int64 __x,
- size_t __n) {
+static __inline__ void __DEFAULT_FN_ATTRS
+__stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
__asm__ __volatile__("rep stosq" : "+D"(__dst), "+c"(__n) : "a"(__x)
: "memory");
}
@@ -572,7 +599,8 @@ __readmsr(unsigned long __register) {
}
#endif
-static __inline__ unsigned __LPTRINT_TYPE__ __DEFAULT_FN_ATTRS __readcr3(void) {
+static __inline__ unsigned __LPTRINT_TYPE__ __DEFAULT_FN_ATTRS
+__readcr3(void) {
unsigned __LPTRINT_TYPE__ __cr3_val;
__asm__ __volatile__ ("mov %%cr3, %0" : "=r"(__cr3_val) : : "memory");
return __cr3_val;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e08e8d8346c0..93479aed36ff 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2048,42 +2048,6 @@ static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID,
llvm_unreachable("unhandled error kind");
}
-FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
- unsigned ID, SourceLocation Loc) {
- DeclContext *Parent = Context.getTranslationUnitDecl();
-
- if (getLangOpts().CPlusPlus) {
- LinkageSpecDecl *CLinkageDecl = LinkageSpecDecl::Create(
- Context, Parent, Loc, Loc, LinkageSpecDecl::lang_c, false);
- CLinkageDecl->setImplicit();
- Parent->addDecl(CLinkageDecl);
- Parent = CLinkageDecl;
- }
-
- FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type,
- /*TInfo=*/nullptr, SC_Extern, false,
- Type->isFunctionProtoType());
- New->setImplicit();
- New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));
-
- // Create Decl objects for each parameter, adding them to the
- // FunctionDecl.
- if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(Type)) {
- SmallVector<ParmVarDecl *, 16> Params;
- for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
- ParmVarDecl *parm = ParmVarDecl::Create(
- Context, New, SourceLocation(), SourceLocation(), nullptr,
- FT->getParamType(i), /*TInfo=*/nullptr, SC_None, nullptr);
- parm->setScopeInfo(0, i);
- Params.push_back(parm);
- }
- New->setParams(Params);
- }
-
- AddKnownFunctionAttributes(New);
- return New;
-}
-
/// LazilyCreateBuiltin - The specified Builtin-ID was first used at
/// file scope. lazily create a decl for it. ForRedeclaration is true
/// if we're creating this built-in in anticipation of redeclaring the
@@ -2134,7 +2098,40 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
if (R.isNull())
return nullptr;
- FunctionDecl *New = CreateBuiltin(II, R, ID, Loc);
+ DeclContext *Parent = Context.getTranslationUnitDecl();
+ if (getLangOpts().CPlusPlus) {
+ LinkageSpecDecl *CLinkageDecl =
+ LinkageSpecDecl::Create(Context, Parent, Loc, Loc,
+ LinkageSpecDecl::lang_c, false);
+ CLinkageDecl->setImplicit();
+ Parent->addDecl(CLinkageDecl);
+ Parent = CLinkageDecl;
+ }
+
+ FunctionDecl *New = FunctionDecl::Create(Context,
+ Parent,
+ Loc, Loc, II, R, /*TInfo=*/nullptr,
+ SC_Extern,
+ false,
+ R->isFunctionProtoType());
+ New->setImplicit();
+
+ // Create Decl objects for each parameter, adding them to the
+ // FunctionDecl.
+ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
+ SmallVector<ParmVarDecl*, 16> Params;
+ for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+ ParmVarDecl *parm =
+ ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(),
+ nullptr, FT->getParamType(i), /*TInfo=*/nullptr,
+ SC_None, nullptr);
+ parm->setScopeInfo(0, i);
+ Params.push_back(parm);
+ }
+ New->setParams(Params);
+ }
+
+ AddKnownFunctionAttributes(New);
RegisterLocallyScopedExternCDecl(New, S);
// TUScope is the translation-unit scope to insert this function into.
@@ -2142,7 +2139,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
// relate Scopes to DeclContexts, and probably eliminate CurContext
// entirely, but we're not there yet.
DeclContext *SavedContext = CurContext;
- CurContext = New->getDeclContext();
+ CurContext = Parent;
PushOnScopeChains(New, TUScope);
CurContext = SavedContext;
return New;
@@ -3367,10 +3364,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
// there but not here.
NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
RequiresAdjustment = true;
- } else if (Old->getBuiltinID()) {
- // Builtin attribute isn't propagated to the new one yet at this point,
- // so we check if the old one is a builtin.
-
+ } else if (New->getBuiltinID()) {
// Calling Conventions on a Builtin aren't really useful and setting a
// default calling convention and cdecl'ing some builtin redeclarations is
// common, so warn and ignore the calling convention on the redeclaration.
@@ -3803,6 +3797,18 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
Diag(OldLocation, diag::note_previous_builtin_declaration)
<< Old << Old->getType();
+
+ // If this is a global redeclaration, just forget hereafter
+ // about the "builtin-ness" of the function.
+ //
+ // Doing this for local extern declarations is problematic. If
+ // the builtin declaration remains visible, a second invalid
+ // local declaration will produce a hard error; if it doesn't
+ // remain visible, a single bogus local redeclaration (which is
+ // actually only a warning) could break all the downstream code.
+ if (!New->getLexicalDeclContext()->isFunctionOrMethod())
+ New->getIdentifier()->revertBuiltin();
+
return false;
}
@@ -9784,36 +9790,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
- // If this is the first declaration of a library builtin function, add
- // attributes as appropriate.
- if (!D.isRedeclaration() &&
- NewFD->getDeclContext()->getRedeclContext()->isFileContext()) {
- if (IdentifierInfo *II = Previous.getLookupName().getAsIdentifierInfo()) {
- if (unsigned BuiltinID = II->getBuiltinID()) {
- if (NewFD->getLanguageLinkage() == CLanguageLinkage) {
- // Validate the type matches unless this builtin is specified as
- // matching regardless of its declared type.
- if (Context.BuiltinInfo.allowTypeMismatch(BuiltinID)) {
- NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
- } else {
- ASTContext::GetBuiltinTypeError Error;
- LookupNecessaryTypesForBuiltin(S, BuiltinID);
- QualType BuiltinType = Context.GetBuiltinType(BuiltinID, Error);
-
- if (!Error && !BuiltinType.isNull() &&
- Context.hasSameFunctionTypeIgnoringExceptionSpec(
- NewFD->getType(), BuiltinType))
- NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
- }
- } else if (BuiltinID == Builtin::BI__GetExceptionInfo &&
- Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- // FIXME: We should consider this a builtin only in the std namespace.
- NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
- }
- }
- }
- }
-
ProcessPragmaWeak(S, NewFD);
checkAttributesAfterMerging(*this, *NewFD);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 02421cbc4317..c33417fd8198 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6252,7 +6252,6 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
Params.push_back(Parm);
}
OverloadDecl->setParams(Params);
- Sema->mergeDeclAttributes(OverloadDecl, FDecl);
return OverloadDecl;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index db6a01543d76..b66c33de83ab 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -935,9 +935,10 @@ bool Sema::LookupBuiltin(LookupResult &R) {
Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
return false;
- if (NamedDecl *D =
- LazilyCreateBuiltin(II, BuiltinID, TUScope,
- R.isForRedeclaration(), R.getNameLoc())) {
+ if (NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II,
+ BuiltinID, TUScope,
+ R.isForRedeclaration(),
+ R.getNameLoc())) {
R.addDecl(D);
return true;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c8290ac5c31b..341d68fbb7cb 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -928,8 +928,9 @@ ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
/// Whether the given identifier is "interesting".
static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II,
bool IsModule) {
- return II.hadMacroDefinition() || II.isPoisoned() ||
- (!IsModule && II.getObjCOrBuiltinID()) ||
+ return II.hadMacroDefinition() ||
+ II.isPoisoned() ||
+ (IsModule ? II.hasRevertedBuiltin() : II.getObjCOrBuiltinID()) ||
II.hasRevertedTokenIDToIdentifier() ||
(!(IsModule && Reader.getPreprocessor().getLangOpts().CPlusPlus) &&
II.getFETokenInfo());
@@ -989,6 +990,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
unsigned Bits = endian::readNext<uint16_t, little, unaligned>(d);
bool CPlusPlusOperatorKeyword = readBit(Bits);
bool HasRevertedTokenIDToIdentifier = readBit(Bits);
+ bool HasRevertedBuiltin = readBit(Bits);
bool Poisoned = readBit(Bits);
bool ExtensionToken = readBit(Bits);
bool HadMacroDefinition = readBit(Bits);
@@ -1002,6 +1004,12 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
II->revertTokenIDToIdentifier();
if (!F.isModule())
II->setObjCOrBuiltinID(ObjCOrBuiltinID);
+ else if (HasRevertedBuiltin && II->getBuiltinID()) {
+ II->revertBuiltin();
+ assert((II->hasRevertedBuiltin() ||
+ II->getObjCOrBuiltinID() == ObjCOrBuiltinID) &&
+ "Incorrect ObjC keyword or builtin ID");
+ }
assert(II->isExtensionToken() == ExtensionToken &&
"Incorrect extension token flag");
(void)ExtensionToken;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 5f038b318e26..2cd5049d2800 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3277,8 +3277,9 @@ class ASTIdentifierTableTrait {
/// doesn't check whether the name has macros defined; use PublicMacroIterator
/// to check that.
bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) {
- if (MacroOffset || II->isPoisoned() ||
- (!IsModule && II->getObjCOrBuiltinID()) ||
+ if (MacroOffset ||
+ II->isPoisoned() ||
+ (IsModule ? II->hasRevertedBuiltin() : II->getObjCOrBuiltinID()) ||
II->hasRevertedTokenIDToIdentifier() ||
(NeedDecls && II->getFETokenInfo()))
return true;
@@ -3374,6 +3375,7 @@ public:
Bits = (Bits << 1) | unsigned(HadMacroDefinition);
Bits = (Bits << 1) | unsigned(II->isExtensionToken());
Bits = (Bits << 1) | unsigned(II->isPoisoned());
+ Bits = (Bits << 1) | unsigned(II->hasRevertedBuiltin());
Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
LE.write<uint16_t>(Bits);
diff --git a/clang/test/AST/ast-dump-attr.cpp b/clang/test/AST/ast-dump-attr.cpp
index c2bd768dc2ad..95491a02f8b2 100644
--- a/clang/test/AST/ast-dump-attr.cpp
+++ b/clang/test/AST/ast-dump-attr.cpp
@@ -119,7 +119,6 @@ namespace Test {
extern "C" int printf(const char *format, ...);
// CHECK: FunctionDecl{{.*}}printf
// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
-// CHECK-NEXT: BuiltinAttr{{.*}}Implicit
// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
alignas(8) extern int x;
diff --git a/clang/test/CodeGen/builtin-redeclaration.c b/clang/test/CodeGen/builtin-redeclaration.c
deleted file mode 100644
index 582907184ea5..000000000000
--- a/clang/test/CodeGen/builtin-redeclaration.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm-only %s
-
-// PR45410
-// Ensure we mark local extern redeclarations with a different type as non-builtin.
-void non_builtin() {
- extern float exp();
- exp(); // Will crash due to wrong number of arguments if this calls the builtin.
-}
-
-// PR45410
-// We mark exp() builtin as const with -fno-math-errno (default).
-// We mustn't do that for extern redeclarations of builtins where the type differs.
-float attribute() {
- extern float exp();
- return exp(1);
-}
diff --git a/clang/test/CodeGen/callback_pthread_create.c b/clang/test/CodeGen/callback_pthread_create.c
index 80457cb3ade3..d1b01b91eac3 100644
--- a/clang/test/CodeGen/callback_pthread_create.c
+++ b/clang/test/CodeGen/callback_pthread_create.c
@@ -1,7 +1,3 @@
-// FIXME: pthread_create() definition in Builtins.def doesn't match the real one, so it doesn't get recognized as a builtin and attributes aren't added.
-// RUN: false
-// XFAIL: *
-
// RUN: %clang_cc1 %s -S -emit-llvm -o - -disable-llvm-optzns | FileCheck %s
// CHECK: declare !callback ![[cid:[0-9]+]] {{.*}}i32 @pthread_create
diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp
index 5a95786beed5..242cba7bc14a 100644
--- a/clang/test/CodeGenCXX/builtins.cpp
+++ b/clang/test/CodeGenCXX/builtins.cpp
@@ -1,19 +1,5 @@
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
-// Builtins inside a namespace inside an extern "C" must be considered builtins.
-extern "C" {
-namespace X {
-double __builtin_fabs(double);
-float __builtin_fabsf(float) noexcept;
-} // namespace X
-}
-
-int o = X::__builtin_fabs(-2.0);
-// CHECK: @o ={{.*}} global i32 2, align 4
-
-long p = X::__builtin_fabsf(-3.0f);
-// CHECK: @p ={{.*}} global i64 3, align 8
-
// PR8839
extern "C" char memmove();
diff --git a/clang/test/Sema/implicit-builtin-decl.c b/clang/test/Sema/implicit-builtin-decl.c
index 9434b507a3af..5ef13cf91df7 100644
--- a/clang/test/Sema/implicit-builtin-decl.c
+++ b/clang/test/Sema/implicit-builtin-decl.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
void f() {
int *ptr = malloc(sizeof(int) * 10); // expected-warning{{implicitly declaring library function 'malloc' with type}} \
@@ -61,5 +62,9 @@ extern float fmaxf(float, float);
struct __jmp_buf_tag {};
void sigsetjmp(struct __jmp_buf_tag[1], int);
+// CHECK: FunctionDecl {{.*}} <line:[[@LINE-2]]:1, col:44> col:6 sigsetjmp '
+// CHECK-NOT: FunctionDecl
+// CHECK: ReturnsTwiceAttr {{.*}} <{{.*}}> Implicit
+
// PR40692
void pthread_create(); // no warning expected
diff --git a/clang/test/Sema/warn-fortify-source.c b/clang/test/Sema/warn-fortify-source.c
index 5ad2979bc29c..0f93a687f007 100644
--- a/clang/test/Sema/warn-fortify-source.c
+++ b/clang/test/Sema/warn-fortify-source.c
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_PASS_OBJECT_SIZE
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_PASS_OBJECT_SIZE
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
typedef unsigned long size_t;
@@ -11,7 +13,13 @@ extern "C" {
extern int sprintf(char *str, const char *format, ...);
-#if defined(USE_BUILTINS)
+#if defined(USE_PASS_OBJECT_SIZE)
+void *memcpy(void *dst, const void *src, size_t c);
+static void *memcpy(void *dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) __asm__("merp");
+static void *memcpy(void *const dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) {
+ return 0;
+}
+#elif defined(USE_BUILTINS)
#define memcpy(x,y,z) __builtin_memcpy(x,y,z)
#else
void *memcpy(void *dst, const void *src, size_t c);
@@ -37,7 +45,14 @@ void call_memcpy_type() {
};
struct pair p;
char buf[20];
- memcpy(&p.first, buf, 20); // expected-warning {{memcpy' will always overflow; destination buffer has size 8, but size argument is 20}}
+ memcpy(&p.first, buf, 20);
+#ifdef USE_PASS_OBJECT_SIZE
+ // Use the more strict checking mode on the pass_object_size attribute:
+ // expected-warning@-3 {{memcpy' will always overflow; destination buffer has size 4, but size argument is 20}}
+#else
+ // Or just fallback to type 0:
+ // expected-warning@-6 {{memcpy' will always overflow; destination buffer has size 8, but size argument is 20}}
+#endif
}
void call_strncat() {
diff --git a/clang/test/SemaCXX/cxx11-compat.cpp b/clang/test/SemaCXX/cxx11-compat.cpp
index f17c900201f7..07cd6b1fcf93 100644
--- a/clang/test/SemaCXX/cxx11-compat.cpp
+++ b/clang/test/SemaCXX/cxx11-compat.cpp
@@ -31,7 +31,7 @@ struct S {
s = { n }, // expected-warning {{non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list in C++11}} expected-note {{explicit cast}}
t = { 1234 }; // expected-warning {{constant expression evaluates to 1234 which cannot be narrowed to type 'char' in C++11}} expected-warning {{changes value}} expected-note {{explicit cast}}
-#define PRIuS "zu"
+#define PRIuS "uS"
int printf(const char *, ...);
typedef __typeof(sizeof(int)) size_t;
void h(size_t foo, size_t bar) {
diff --git a/clang/test/SemaCXX/warn-unused-local-typedef.cpp b/clang/test/SemaCXX/warn-unused-local-typedef.cpp
index 554ea37eeb28..7e893ba506a5 100644
--- a/clang/test/SemaCXX/warn-unused-local-typedef.cpp
+++ b/clang/test/SemaCXX/warn-unused-local-typedef.cpp
@@ -67,10 +67,10 @@ int printf(char const *, ...);
void test() {
typedef signed long int superint; // no diag
- printf("%ld", (superint)42);
+ printf("%f", (superint) 42);
typedef signed long int superint2; // no diag
- printf("%ld", static_cast<superint2>(42));
+ printf("%f", static_cast<superint2>(42));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-local-typedef"
--
2.32.0.272.g935e593368-goog