summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-02-14 09:06:43 +0000
committerHans Wennborg <hans@hanshq.net>2018-02-14 09:06:43 +0000
commit4a0ce84710b48d724e67ec29e71da5f6accf01be (patch)
treeb497d9309becb3922d56bb1d2c920d0b472b00b3
parent4a005620928c39874a0177ec97d84e636ab8dbfc (diff)
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
-rw-r--r--lib/Sema/SemaDecl.cpp10
-rw-r--r--test/Sema/bitfield.c4
-rw-r--r--test/Sema/cxx-as-c.c9
3 files changed, 23 insertions, 0 deletions
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+{{}}