diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-25 16:33:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-25 16:33:18 +0000 |
commit | 2224f84658fb9b3725a31f2680edb64ae73bf705 (patch) | |
tree | d8b3f0a9bfc05c8565e35df1c47b5cc649377136 /lib/Sema | |
parent | 70f2a0485dd81e6684553eb5537a27db4176ed45 (diff) |
C99 DR #316 implies that the function parameter types that are known
only from a function definition (that does not have a prototype) are
only used to determine the compatible with other declarations of that
same function. In particular, when referencing the function we pretend
as if it does not have a prototype. Implement this behavior, which
fixes PR3626.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 |
3 files changed, 21 insertions, 2 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index abb5e40dd4..c312195972 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -334,7 +334,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, FunctionDecl *New = FunctionDecl::Create(Context, Context.getTranslationUnitDecl(), Loc, II, R, - FunctionDecl::Extern, false); + FunctionDecl::Extern, false, + /*hasPrototype=*/true); New->setImplicit(); // Create Decl objects for each parameter, adding them to the @@ -1736,6 +1737,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // code path. NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(), Name, R, SC, isInline, + /*hasPrototype=*/true, // FIXME: Move to DeclGroup... D.getDeclSpec().getSourceRange().getBegin()); InvalidDecl = true; @@ -1765,6 +1767,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(), Name, R, SC, isInline, + /*hasPrototype=*/ + (getLangOptions().CPlusPlus || + (D.getNumTypeObjects() && + D.getTypeObject(0).Fun.hasPrototype)), // FIXME: Move to DeclGroup... D.getDeclSpec().getSourceRange().getBegin()); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 174e408ead..98d6b12b9c 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -873,6 +873,19 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, CheckS = CheckS->getParent(); } } + } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(VD)) { + if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) { + // C99 DR 316 says that, if a function type comes from a + // function definition (without a prototype), that type is only + // used for checking compatibility. Therefore, when referencing + // the function, we pretend that we don't have the full function + // type. + QualType T = Func->getType(); + QualType NoProtoType = T; + if (const FunctionTypeProto *Proto = T->getAsFunctionTypeProto()) + NoProtoType = Context.getFunctionTypeNoProto(Proto->getResultType()); + return Owned(BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS)); + } } // Only create DeclRefExpr's for valid Decl's. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index ea59b644c9..c8671bc2e3 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -543,7 +543,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0); FunctionDecl *Alloc = FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name, - FnType, FunctionDecl::None, false, + FnType, FunctionDecl::None, false, true, SourceLocation()); Alloc->setImplicit(); ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(), |