[cfe-commits] r64504 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Sema/ test/Analysis/ test/CodeGen/ test/Sema/
Howard Hinnant
hhinnant at apple.com
Fri Feb 13 15:36:10 PST 2009
Is this feature switched off in C++? Since one must have a prototype
in C++, I think it should be. And a test ensuring that fact would be
comforting (I skimmed, and may have missed it). It it isn't turned
off in C++, I'm wondering how headers like <cstring> will handle
adding the C++-required overloads to some of these functions. e.g.:
namespace std {
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
} // std
I.e. will the compiler complain?
It would also be nice to not automagically pollute the global
namespace with these names in C++, even though we currently do so
anyway by including most any C++ std::lib header (with C++0X we're
even allowed to do so).
-Howard
On Feb 13, 2009, at 6:20 PM, Douglas Gregor wrote:
> Author: dgregor
> Date: Fri Feb 13 17:20:09 2009
> New Revision: 64504
>
> URL: http://llvm.org/viewvc/llvm-project?rev=64504&view=rev
> Log:
> Implicitly declare certain C library functions (malloc, strcpy,
> memmove,
> etc.) when we perform name lookup on them. This ensures that we
> produce the correct signature for these functions, which has two
> practical impacts:
>
> 1) When we're supporting the "implicit function declaration" feature
> of C99, these functions will be implicitly declared with the right
> signature rather than as a function returning "int" with no
> prototype. See PR3541 for the reason why this is important (hint:
> GCC always predeclares these functions).
>
> 2) If users attempt to redeclare one of these library functions with
> an incompatible signature, we produce a hard error.
>
> This patch does a little bit of work to give reasonable error
> messages. For example, when we hit case #1 we complain that we're
> implicitly declaring this function with a specific signature, and then
> we give a note that asks the user to include the appropriate header
> (e.g., "please include <stdlib.h> or explicitly declare 'malloc'"). In
> case #2, we show the type of the implicit builtin that was incorrectly
> declared, so the user can see the problem. We could do better here:
> for example, when displaying this latter error message we say
> something like:
>
> 'strcpy' was implicitly declared here with type 'char *(char *, char
> const *)'
>
> but we should really print out a fake code line showing the
> declaration, like this:
>
> 'strcpy' was implicitly declared here as:
>
> char *strcpy(char *, char const *)
>
> This would also be good for printing built-in candidates with C++
> operator overloading.
>
> The set of C library functions supported by this patch includes all
> functions from the C99 specification's <stdlib.h> and <string.h> that
> (a) are predefined by GCC and (b) have signatures that could cause
> codegen issues if they are treated as functions with no prototype
> returning and int. Future work could extend this set of functions to
> other C library functions that we know about.
>
>
>
> Added:
> cfe/trunk/test/Sema/implicit-builtin-decl.c
> Modified:
> cfe/trunk/include/clang/AST/Builtins.def
> cfe/trunk/include/clang/AST/Builtins.h
> cfe/trunk/include/clang/AST/Decl.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/AST/Expr.cpp
> cfe/trunk/lib/Analysis/GRExprEngine.cpp
> cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> cfe/trunk/lib/CodeGen/CGExpr.cpp
> cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> cfe/trunk/lib/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaChecking.cpp
> cfe/trunk/lib/Sema/SemaDecl.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaLookup.cpp
> cfe/trunk/lib/Sema/SemaUtil.h
> cfe/trunk/test/Analysis/exercise-ps.c
> cfe/trunk/test/CodeGen/merge-attrs.c
>
> Modified: cfe/trunk/include/clang/AST/Builtins.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Builtins.def?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/Builtins.def (original)
> +++ cfe/trunk/include/clang/AST/Builtins.def Fri Feb 13 17:20:09 2009
> @@ -54,6 +54,10 @@
> // n -> nothrow
> // c -> const
> // F -> this is a libc/libm function with a '__builtin_' prefix
> added.
> +// f -> this is a libc/libm function without the '__builtin_'
> prefix. It can
> +// be followed by ':headername' to state which header this
> function
> +// comes from, but only if 'f:headername' is the last part of
> the
> +// string.
> // FIXME: gcc has nonnull
>
> // Standard libc/libm functions:
> @@ -172,4 +176,23 @@
> // LLVM instruction builtin
> BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")
>
> +// Builtin library functions
> +BUILTIN(alloca, "v*z", "f:stdlib.h")
> +BUILTIN(calloc, "v*zz", "f:stdlib.h")
> +BUILTIN(malloc, "v*z", "f:stdlib.h")
> +BUILTIN(memcpy, "v*v*vC*z", "f:string.h")
> +BUILTIN(memmove, "v*v*vC*z", "f:string.h")
> +BUILTIN(memset, "v*v*iz", "f:string.h")
> +BUILTIN(strcat, "c*c*cC*", "f:string.h")
> +BUILTIN(strchr, "c*cC*i", "f:string.h")
> +BUILTIN(strcpy, "c*c*cC*", "f:string.h")
> +BUILTIN(strcspn, "zcC*cC*", "f:string.h")
> +BUILTIN(strlen, "zcC*", "f:string.h")
> +BUILTIN(strncat, "c*c*cC*z", "f:string.h")
> +BUILTIN(strncpy, "c*c*cC*z", "f:string.h")
> +BUILTIN(strpbrk, "c*cC*cC*", "f:string.h")
> +BUILTIN(strrchr, "c*cC*i", "f:string.h")
> +BUILTIN(strspn, "zcC*cC*", "f:string.h")
> +BUILTIN(strstr, "c*cC*cC*", "f:string.h")
> +
> #undef BUILTIN
>
> Modified: cfe/trunk/include/clang/AST/Builtins.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Builtins.h?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/Builtins.h (original)
> +++ cfe/trunk/include/clang/AST/Builtins.h Fri Feb 13 17:20:09 2009
> @@ -78,6 +78,27 @@
> return strchr(GetRecord(ID).Attributes, 'F') != 0;
> }
>
> + /// \brief Determines whether this builtin is a predefined libc/
> libm
> + /// function, such as "malloc", where we know the signature a
> + /// priori.
> + bool isPredefinedLibFunction(unsigned ID) const {
> + return strchr(GetRecord(ID).Attributes, 'f') != 0;
> + }
> +
> + /// \brief If this is a library function that comes from a specific
> + /// header, retrieve that header name.
> + const char *getHeaderName(unsigned ID) const {
> + char *Name = strchr(GetRecord(ID).Attributes, 'f');
> + if (!Name)
> + return 0;
> + ++Name;
> +
> + if (*Name != ':')
> + return 0;
> +
> + return ++Name;
> + }
> +
> /// hasVAListUse - Return true of the specified builtin uses
> __builtin_va_list
> /// as an operand or return type.
> bool hasVAListUse(unsigned ID) const {
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Fri Feb 13 17:20:09 2009
> @@ -600,6 +600,8 @@
> PreviousDeclaration = PrevDecl;
> }
>
> + unsigned getBuiltinID() const;
> +
> // Iterator access to formal parameters.
> unsigned param_size() const { return getNumParams(); }
> typedef ParmVarDecl **param_iterator;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Fri Feb 13
> 17:20:09 2009
> @@ -84,6 +84,14 @@
> DIAG(err_bad_language, ERROR,
> "unknown linkage language")
>
> +/// Built-in functions.
> +DIAG(ext_implicit_lib_function_decl, EXTWARN,
> + "implicitly declaring C library function '%0' with type %1")
> +DIAG(note_please_include_header, NOTE,
> + "please include the header <%0> or explicitly provide a
> declaration for '%1'")
> +DIAG(note_previous_builtin_declaration, NOTE,
> + "%0 was implicitly declared here with type %1")
> +
> /// parser diagnostics
> DIAG(ext_typedef_without_a_name, EXTWARN,
> "typedef requires a name")
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Fri Feb 13 17:20:09 2009
> @@ -250,6 +250,28 @@
> return 0;
> }
>
> +/// \brief Returns a value indicating whether this function
> +/// corresponds to a builtin function.
> +///
> +/// The function corresponds to a built-in function if it is
> +/// declared at translation scope or within an extern "C" block and
> +/// its name matches with the name of a builtin. The returned value
> +/// will be 0 for functions that do not correspond to a builtin, a
> +/// value of type \c Builtin::ID if in the target-independent range
> +/// \c [1,Builtin::First), or a target-specific builtin value.
> +unsigned FunctionDecl::getBuiltinID() const {
> + if (getIdentifier() &&
> + (getDeclContext()->isTranslationUnit() ||
> + (isa<LinkageSpecDecl>(getDeclContext()) &&
> + cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
> + == LinkageSpecDecl::lang_c)))
> + return getIdentifier()->getBuiltinID();
> +
> + // Not a builtin.
> + return 0;
> +}
> +
> +
> // Helper function for FunctionDecl::getNumParams and
> FunctionDecl::setParams()
> static unsigned getNumTypeParams(QualType T) {
> const FunctionType *FT = T->getAsFunctionType();
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Fri Feb 13 17:20:09 2009
> @@ -192,7 +192,7 @@
> if (!FDecl->getIdentifier())
> return 0;
>
> - return FDecl->getIdentifier()->getBuiltinID();
> + return FDecl->getBuiltinID();
> }
>
>
>
> Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
> +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Feb 13 17:20:09 2009
> @@ -1269,9 +1269,7 @@
>
> if (isa<loc::FuncVal>(L)) {
>
> - IdentifierInfo* Info = cast<loc::FuncVal>(L).getDecl()-
> >getIdentifier();
> -
> - if (unsigned id = Info->getBuiltinID())
> + if (unsigned id = cast<loc::FuncVal>(L).getDecl()-
> >getBuiltinID())
> switch (id) {
> case Builtin::BI__builtin_expect: {
> // For __builtin_expect, just return the value of the
> subexpression.
>
> Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Fri Feb 13 17:20:09 2009
> @@ -327,7 +327,8 @@
>
> // If this is an alias for a libm function (e.g. __builtin_sin)
> turn it into
> // that function.
> - if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
> + if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
> + getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
> return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
> E->getCallee()->getType(), E->arg_begin(),
> E->arg_end());
>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Feb 13 17:20:09 2009
> @@ -964,7 +964,7 @@
> dyn_cast<const DeclRefExpr>(IcExpr->getSubExpr()))
> if (const FunctionDecl *FDecl =
> dyn_cast<const FunctionDecl>(DRExpr->getDecl()))
> - if (unsigned builtinID = FDecl->getIdentifier()-
> >getBuiltinID())
> + if (unsigned builtinID = FDecl->getBuiltinID())
> return EmitBuiltinExpr(builtinID, E);
>
> if (E->getCallee()->getType()->isBlockPointerType())
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb 13 17:20:09 2009
> @@ -842,10 +842,14 @@
> if (FunctionSlot)
> return FunctionSlot;
>
> - assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a
> lib fn");
> -
> - // Get the name, skip over the __builtin_ prefix.
> - const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10;
> + assert((Context.BuiltinInfo.isLibFunction(BuiltinID) ||
> + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) &&
> + "isn't a lib fn");
> +
> + // Get the name, skip over the __builtin_ prefix (if necessary).
> + const char *Name = Context.BuiltinInfo.GetName(BuiltinID);
> + if (Context.BuiltinInfo.isLibFunction(BuiltinID))
> + Name += 10;
>
> // Get the type for the builtin.
> QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID,
> Context);
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Fri Feb 13 17:20:09 2009
> @@ -864,14 +864,18 @@
>
> LookupResult LookupName(Scope *S, DeclarationName Name,
> LookupNameKind NameKind,
> - bool RedeclarationOnly = false);
> + bool RedeclarationOnly = false,
> + bool AllowBuiltinCreation = true,
> + SourceLocation Loc = SourceLocation());
> LookupResult LookupQualifiedName(DeclContext *LookupCtx,
> DeclarationName Name,
> LookupNameKind NameKind,
> bool RedeclarationOnly = false);
> LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS,
> DeclarationName Name,
> LookupNameKind NameKind,
> - bool RedeclarationOnly = false);
> + bool RedeclarationOnly = false,
> + bool AllowBuiltinCreation = true,
> + SourceLocation Loc =
> SourceLocation());
>
> typedef llvm::SmallPtrSet<NamespaceDecl *, 16>
> AssociatedNamespaceSet;
> typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
> @@ -887,7 +891,8 @@
>
> ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
> NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
> - Scope *S);
> + Scope *S, bool ForRedeclaration,
> + SourceLocation Loc);
> NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc,
> IdentifierInfo &II,
> Scope *S);
>
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb 13 17:20:09 2009
> @@ -34,7 +34,7 @@
> if (!FnInfo)
> return move(TheCallResult);
>
> - switch (FnInfo->getBuiltinID()) {
> + switch (FDecl->getBuiltinID()) {
> case Builtin::BI__builtin___CFStringMakeConstantString:
> assert(TheCall->getNumArgs() == 1 &&
> "Wrong # arguments to builtin CFStringMakeConstantString");
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb 13 17:20:09 2009
> @@ -45,7 +45,8 @@
> Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation
> NameLoc,
> Scope *S, const CXXScopeSpec *SS) {
> Decl *IIDecl = 0;
> - LookupResult Result = LookupParsedName(S, SS, &II,
> LookupOrdinaryName, false);
> + LookupResult Result = LookupParsedName(S, SS, &II,
> LookupOrdinaryName,
> + false, false);
> switch (Result.getKind()) {
> case LookupResult::NotFound:
> case LookupResult::FoundOverloaded:
> @@ -285,21 +286,38 @@
> Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
> }
>
> -/// LazilyCreateBuiltin - The specified Builtin-ID was first used
> at file scope.
> -/// lazily create a decl for it.
> +/// 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
> +/// built-in.
> NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
> - Scope *S) {
> + Scope *S, bool ForRedeclaration,
> + SourceLocation Loc) {
> Builtin::ID BID = (Builtin::ID)bid;
>
> if (Context.BuiltinInfo.hasVAListUse(BID))
> InitBuiltinVaListType();
> -
> +
> QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
> +
> + if (!ForRedeclaration &&
> Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
> + Diag(Loc, diag::ext_implicit_lib_function_decl)
> + << Context.BuiltinInfo.GetName(BID)
> + << R;
> + if (Context.BuiltinInfo.getHeaderName(BID) &&
> +
> Diags.getDiagnosticMapping(diag::ext_implicit_lib_function_decl)
> + != diag::MAP_IGNORE)
> + Diag(Loc, diag::note_please_include_header)
> + << Context.BuiltinInfo.getHeaderName(BID)
> + << Context.BuiltinInfo.GetName(BID);
> + }
> +
> FunctionDecl *New = FunctionDecl::Create(Context,
>
> Context.getTranslationUnitDecl(),
> - SourceLocation(), II, R,
> + Loc, II, R,
> FunctionDecl::Extern,
> false);
> -
> + New->setImplicit();
> +
> // Create Decl objects for each parameter, adding them to the
> // FunctionDecl.
> if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(R)) {
> @@ -491,9 +509,12 @@
> diag::kind PrevDiag;
> if (Old->isThisDeclarationADefinition())
> PrevDiag = diag::note_previous_definition;
> - else if (Old->isImplicit())
> - PrevDiag = diag::note_previous_implicit_declaration;
> - else
> + else if (Old->isImplicit()) {
> + if (Old->getBuiltinID())
> + PrevDiag = diag::note_previous_builtin_declaration;
> + else
> + PrevDiag = diag::note_previous_implicit_declaration;
> + } else
> PrevDiag = diag::note_previous_declaration;
>
> QualType OldQType = Context.getCanonicalType(Old->getType());
> @@ -510,7 +531,7 @@
> = cast<FunctionType>(NewQType.getTypePtr())->getResultType();
> if (OldReturnType != NewReturnType) {
> Diag(New->getLocation(), diag::err_ovl_diff_return_type);
> - Diag(Old->getLocation(), PrevDiag);
> + Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
> Redeclaration = true;
> return New;
> }
> @@ -523,7 +544,7 @@
> // is a static member function declaration.
> if (OldMethod->isStatic() || NewMethod->isStatic()) {
> Diag(New->getLocation(),
> diag::err_ovl_static_nonstatic_member);
> - Diag(Old->getLocation(), PrevDiag);
> + Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
> return New;
> }
>
> @@ -544,7 +565,7 @@
> NewDiag = diag::err_member_redeclared;
>
> Diag(New->getLocation(), NewDiag);
> - Diag(Old->getLocation(), PrevDiag);
> + Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
> }
> }
>
> @@ -577,7 +598,7 @@
> // TODO: This is totally simplistic. It should handle merging
> functions
> // together etc, merging extern int X; int X; ...
> Diag(New->getLocation(), diag::err_conflicting_types) << New-
> >getDeclName();
> - Diag(Old->getLocation(), PrevDiag);
> + Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
> return New;
> }
>
> @@ -1217,10 +1238,11 @@
> // See if this is a redefinition of a variable in the same scope.
> if (!D.getCXXScopeSpec().isSet() && !
> D.getCXXScopeSpec().isInvalid()) {
> DC = CurContext;
> - PrevDecl = LookupName(S, Name, LookupOrdinaryName);
> + PrevDecl = LookupName(S, Name, LookupOrdinaryName, true, true,
> + D.getIdentifierLoc());
> } else { // Something like "int foo::x;"
> DC = static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep());
> - PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
> + PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName,
> true);
>
> // C++ 7.3.1.2p2:
> // Members (including explicit specializations of templates) of
> a named
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb 13 17:20:09 2009
> @@ -547,7 +547,8 @@
> // Could be enum-constant, value decl, instance variable, etc.
> if (SS && SS->isInvalid())
> return ExprError();
> - LookupResult Lookup = LookupParsedName(S, SS, Name,
> LookupOrdinaryName);
> + LookupResult Lookup = LookupParsedName(S, SS, Name,
> LookupOrdinaryName,
> + false, true, Loc);
>
> if (getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
> HasTrailingLParen && Lookup.getKind() ==
> LookupResult::NotFound) {
> @@ -1922,9 +1923,8 @@
> }
>
> if (Ovl || (getLangOptions().CPlusPlus && (FDecl ||
> UnqualifiedName))) {
> - // We don't perform ADL for builtins.
> - if (FDecl && FDecl->getIdentifier() &&
> - FDecl->getIdentifier()->getBuiltinID())
> + // We don't perform ADL for implicit declarations of builtins.
> + if (FDecl && FDecl->getBuiltinID() && FDecl->isImplicit())
> ADL = false;
>
> // We don't perform ADL in C.
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Feb 13 17:20:09 2009
> @@ -728,21 +728,17 @@
> ///
> /// @param Name The name of the entity that we are searching for.
> ///
> -/// @param Criteria The criteria that this routine will use to
> -/// determine which names are visible and which names will be
> -/// found. Note that name lookup will find a name that is visible by
> -/// the given criteria, but the entity itself may not be semantically
> -/// correct or even the kind of entity expected based on the
> -/// lookup. For example, searching for a nested-name-specifier name
> -/// might result in an EnumDecl, which is visible but is not
> permitted
> -/// as a nested-name-specifier in C++03.
> +/// @param Loc If provided, the source location where we're
> performing
> +/// name lookup. At present, this is only used to produce
> diagnostics when
> +/// C library functions (like "malloc") are implicitly declared.
> ///
> /// @returns The result of name lookup, which includes zero or more
> /// declarations and possibly additional information used to diagnose
> /// ambiguities.
> Sema::LookupResult
> Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind
> NameKind,
> - bool RedeclarationOnly) {
> + bool RedeclarationOnly, bool AllowBuiltinCreation,
> + SourceLocation Loc) {
> if (!Name) return LookupResult::CreateLookupResult(Context, 0);
>
> if (!getLangOptions().CPlusPlus) {
> @@ -812,12 +808,19 @@
> // now, injecting it into translation unit scope, and return it.
> if (NameKind == LookupOrdinaryName) {
> IdentifierInfo *II = Name.getAsIdentifierInfo();
> - if (II) {
> + if (II && AllowBuiltinCreation) {
> // If this is a builtin on this (or all) targets, create the
> decl.
> - if (unsigned BuiltinID = II->getBuiltinID())
> + if (unsigned BuiltinID = II->getBuiltinID()) {
> + // In C++, we don't have any predefined library functions
> like
> + // 'malloc'. Instead, we'll just error.
> + if (getLangOptions().CPlusPlus &&
> + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
> + return LookupResult::CreateLookupResult(Context, 0);
> +
> return LookupResult::CreateLookupResult(Context,
> LazilyCreateBuiltin((IdentifierInfo
> *)II, BuiltinID,
> - S));
> + S,
> RedeclarationOnly, Loc));
> + }
> }
> if (getLangOptions().ObjC1 && II) {
> // @interface and @compatibility_alias introduce typedef-like
> names.
> @@ -995,11 +998,16 @@
> /// @param Name The name of the entity that name lookup will
> /// search for.
> ///
> +/// @param Loc If provided, the source location where we're
> performing
> +/// name lookup. At present, this is only used to produce
> diagnostics when
> +/// C library functions (like "malloc") are implicitly declared.
> +///
> /// @returns The result of qualified or unqualified name lookup.
> Sema::LookupResult
> Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
> DeclarationName Name, LookupNameKind NameKind,
> - bool RedeclarationOnly) {
> + bool RedeclarationOnly, bool
> AllowBuiltinCreation,
> + SourceLocation Loc) {
> if (SS) {
> if (SS->isInvalid())
> return LookupResult::CreateLookupResult(Context, 0);
> @@ -1009,7 +1017,8 @@
> Name, NameKind, RedeclarationOnly);
> }
>
> - return LookupName(S, Name, NameKind, RedeclarationOnly);
> + return LookupName(S, Name, NameKind, RedeclarationOnly,
> + AllowBuiltinCreation, Loc);
> }
>
>
>
> Modified: cfe/trunk/lib/Sema/SemaUtil.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaUtil.h?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaUtil.h (original)
> +++ cfe/trunk/lib/Sema/SemaUtil.h Fri Feb 13 17:20:09 2009
> @@ -24,8 +24,9 @@
> Expr* sub = cexp->getCallee()->IgnoreParenCasts();
>
> if (DeclRefExpr* E = dyn_cast<DeclRefExpr>(sub))
> - if (E->getDecl()->getIdentifier()->getBuiltinID() > 0)
> - return true;
> + if (FunctionDecl *Fn = dyn_cast<FunctionDecl>(E->getDecl()))
> + if (Fn->getBuiltinID() > 0)
> + return true;
>
> return false;
> }
>
> Modified: cfe/trunk/test/Analysis/exercise-ps.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exercise-ps.c?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/Analysis/exercise-ps.c (original)
> +++ cfe/trunk/test/Analysis/exercise-ps.c Fri Feb 13 17:20:09 2009
> @@ -20,5 +20,6 @@
> static void f2(void *buf) {
> F12_typedef* x;
> x = f2_helper();
> - memcpy((&x[1]), (buf), 1);
> + memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly
> declaring C library function 'memcpy' with type 'void *(void *, void
> const *}} \
> + // expected-note{{please include the header <string.h> or
> explicitly provide a declaration for 'memcpy'}}
> }
>
> Modified: cfe/trunk/test/CodeGen/merge-attrs.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/merge-attrs.c?rev=64504&r1=64503&r2=64504&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/CodeGen/merge-attrs.c (original)
> +++ cfe/trunk/test/CodeGen/merge-attrs.c Fri Feb 13 17:20:09 2009
> @@ -1,12 +1,12 @@
> // RUN: clang %s -emit-llvm -o %t
>
> -void *malloc(int size) __attribute__ ((__nothrow__));
> +void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__));
>
> inline static void __zend_malloc() {
> malloc(1);
> }
>
> -void *malloc(int size) __attribute__ ((__nothrow__));
> +void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__));
>
> void fontFetch() {
> __zend_malloc(1);
>
> Added: cfe/trunk/test/Sema/implicit-builtin-decl.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/implicit-builtin-decl.c?rev=64504&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/Sema/implicit-builtin-decl.c (added)
> +++ cfe/trunk/test/Sema/implicit-builtin-decl.c Fri Feb 13 17:20:09
> 2009
> @@ -0,0 +1,22 @@
> +// RUN: clang -fsyntax-only -verify %s
> +void f() {
> + int *ptr = malloc(sizeof(int) * 10); // expected-
> warning{{implicitly declaring C library function 'malloc' with
> type}} \
> + // expected-note{{please include the header <stdlib.h> or
> explicitly provide a declaration for 'malloc'}} \
> + // expected-note{{'malloc' was implicitly declared here with type
> 'void *}}
> +}
> +
> +void *alloca(__SIZE_TYPE__); // redeclaration okay
> +
> +int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-
> error{{conflicting types for 'calloc'}} \
> + // expected-note{{'calloc' was implicitly
> declared here with type 'void *}}
> +
> +
> +void g(int malloc) { // okay: these aren't functions
> + int calloc = 1;
> +}
> +
> +void h() {
> + int malloc(int); // expected-error{{conflicting types for
> 'malloc'}}
> + int strcpy(int); // expected-error{{conflicting types for
> 'strcpy'}} \
> + // expected-note{{'strcpy' was implicitly declared here with type
> 'char *(char *, char const *)'}}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list