PR36157: When injecting an implicit function declaration in C89, find the right

DeclContext rather than injecting it wherever we happen to be.

This avoids creating functions whose DeclContext is a struct or similar.

llvm-svn: 323998
This commit is contained in:
Richard Smith 2018-02-01 20:01:49 +00:00
parent 8c4ca0bbea
commit 081cbe9696
3 changed files with 23 additions and 0 deletions

View File

@ -12910,10 +12910,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,
/// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
IdentifierInfo &II, Scope *S) {
// Find the scope in which the identifier is injected and the corresponding
// DeclContext.
// FIXME: C89 does not say what happens if there is no enclosing block scope.
// In that case, we inject the declaration into the translation unit scope
// instead.
Scope *BlockScope = S;
while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent())
BlockScope = BlockScope->getParent();
Scope *ContextScope = BlockScope;
while (!ContextScope->getEntity())
ContextScope = ContextScope->getParent();
ContextRAII SavedContext(*this, ContextScope->getEntity());
// Before we produce a declaration for an implicitly defined
// function, see whether there was a locally-scoped declaration of
// this name as a function or variable. If so, use that

View File

@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act like compound-assignment.
struct Test6 {
: 0.0; // expected-error{{type name requires a specifier or qualifier}}
};
struct PR36157 {
int n : 1 ? 1 : implicitly_declare_function(); // expected-warning {{invalid in C99}}
};

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 %s -verify
// PR36157
struct Foo {
Foo(int n) : n_(n) {} // expected-error 1+{{}} expected-warning 1+{{}}
private:
int n;
};
int main() { Foo f; } // expected-error 1+{{}}