]> granicus.if.org Git - clang/commitdiff
PR20769: Fix confusion when checking whether a prior default argument was in
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 22:31:34 +0000 (22:31 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 22:31:34 +0000 (22:31 +0000)
scope when checking for conflicts.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216628 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/IdentifierResolver.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/default1.cpp

index 2a5bacff0d93f788d539aaa08d2b9a4d19e5c16f..6586fb32787c12c92cfbd82734c029c61901ebc1 100644 (file)
@@ -130,6 +130,9 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
     return false;
   }
 
+  // FIXME: If D is a local extern declaration, this check doesn't make sense;
+  // we should be checking its lexical context instead in that case, because
+  // that is its scope.
   DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
   return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
                               : Ctx->Equals(DCtx);
index 081d91e05062f0d9313fa28b01a8c84b3730a50e..f0925e478b18c7291d7d0fda7b089a97b8764c04 100644 (file)
@@ -446,20 +446,24 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
     bool OldParamHasDfl = OldParam->hasDefaultArg();
     bool NewParamHasDfl = NewParam->hasDefaultArg();
 
-    NamedDecl *ND = Old;
-
     // The declaration context corresponding to the scope is the semantic
     // parent, unless this is a local function declaration, in which case
     // it is that surrounding function.
-    DeclContext *ScopeDC = New->getLexicalDeclContext();
-    if (!ScopeDC->isFunctionOrMethod())
-      ScopeDC = New->getDeclContext();
-    if (S && !isDeclInScope(ND, ScopeDC, S) &&
+    DeclContext *ScopeDC = New->isLocalExternDecl()
+                               ? New->getLexicalDeclContext()
+                               : New->getDeclContext();
+    if (S && !isDeclInScope(Old, ScopeDC, S) &&
         !New->getDeclContext()->isRecord())
       // Ignore default parameters of old decl if they are not in
       // the same scope and this is not an out-of-line definition of
       // a member function.
       OldParamHasDfl = false;
+    if (New->isLocalExternDecl() != Old->isLocalExternDecl())
+      // If only one of these is a local function declaration, then they are
+      // declared in different scopes, even though isDeclInScope may think
+      // they're in the same scope. (If both are local, the scope check is
+      // sufficent, and if neither is local, then they are in the same scope.)
+      OldParamHasDfl = false;
 
     if (OldParamHasDfl && NewParamHasDfl) {
 
index 23466fac62aaaaaee25237a617eabf2499dc6043..6001001b11eb9e2cbae53166c8e9305359705134 100644 (file)
@@ -65,3 +65,9 @@ int i2() {
 
 int pr20055_f(int x = 0, int y = UNDEFINED); // expected-error{{use of undeclared identifier}}
 int pr20055_v = pr20055_f(0);
+
+void PR20769() { void PR20769(int = 1); }
+void PR20769(int = 2);
+
+void PR20769_b(int = 1);
+void PR20769_b() { void PR20769_b(int = 2); }