From 4a0ce84710b48d724e67ec29e71da5f6accf01be Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 14 Feb 2018 09:06:43 +0000 Subject: Merging r323998: ------------------------------------------------------------------------ r323998 | rsmith | 2018-02-01 21:01:49 +0100 (Thu, 01 Feb 2018) | 5 lines 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. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_60@325104 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 10 ++++++++++ test/Sema/bitfield.c | 4 ++++ test/Sema/cxx-as-c.c | 9 +++++++++ 3 files changed, 23 insertions(+) create mode 100644 test/Sema/cxx-as-c.c diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 743f4bb5e8..7ca48c34e5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12507,10 +12507,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 diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index d625366e4e..13e9480a37 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -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}} +}; diff --git a/test/Sema/cxx-as-c.c b/test/Sema/cxx-as-c.c new file mode 100644 index 0000000000..41d7350d1f --- /dev/null +++ b/test/Sema/cxx-as-c.c @@ -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+{{}} -- cgit v1.2.3