else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
/* Inline decls shadow nothing. */
&& !DECL_FROM_INLINE (x)
- && TREE_CODE (oldlocal) == PARM_DECL
+ && (TREE_CODE (oldlocal) == PARM_DECL
+ || TREE_CODE (oldlocal) == VAR_DECL)
/* Don't check the `this' parameter. */
- && !DECL_ARTIFICIAL (oldlocal))
+ && !DECL_ARTIFICIAL (oldlocal)
+ && !DECL_ARTIFICIAL (x))
{
- bool err = false;
+ bool nowarn = false;
/* Don't complain if it's from an enclosing function. */
if (DECL_CONTEXT (oldlocal) == current_function_decl
- && TREE_CODE (x) != PARM_DECL)
+ && TREE_CODE (x) != PARM_DECL
+ && TREE_CODE (oldlocal) == PARM_DECL)
{
/* Go to where the parms should be and see if we find
them there. */
if (b->kind == sk_function_parms)
{
error ("declaration of %q#D shadows a parameter", x);
- err = true;
+ nowarn = true;
}
}
- if (warn_shadow && !err)
+ /* The local structure or class can't use parameters of
+ the containing function anyway. */
+ if (DECL_CONTEXT (oldlocal) != current_function_decl)
{
- warning_at (input_location, OPT_Wshadow,
- "declaration of %q#D shadows a parameter", x);
- warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
- "shadowed declaration is here");
+ cxx_scope *scope = current_binding_level;
+ tree context = DECL_CONTEXT (oldlocal);
+ for (; scope; scope = scope->level_chain)
+ {
+ if (scope->kind == sk_function_parms
+ && scope->this_entity == context)
+ break;
+ if (scope->kind == sk_class
+ && !LAMBDA_TYPE_P (scope->this_entity))
+ {
+ nowarn = true;
+ break;
+ }
+ }
+ }
+
+ if (warn_shadow && !nowarn)
+ {
+ if (TREE_CODE (oldlocal) == PARM_DECL)
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %q#D shadows a parameter", x);
+ else
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a previous local",
+ x);
+ warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+ "shadowed declaration is here");
}
}
warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
x);
}
- else if (oldlocal != NULL_TREE
- && TREE_CODE (oldlocal) == VAR_DECL)
- {
- warning_at (input_location, OPT_Wshadow,
- "declaration of %qD shadows a previous local", x);
- warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
- "shadowed declaration is here");
- }
else if (oldglobal != NULL_TREE
&& TREE_CODE (oldglobal) == VAR_DECL)
/* XXX shadow warnings in outer-more namespaces */
int GetMainURL() const;
};
-int foo(int infoo) // { dg-warning "shadowed declaration" }
+int foo(int infoo) // { dg-bogus "shadowed declaration" }
{
int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" }
extern void f(int infoo);
struct A
{
- void f(int infoo) { } // { dg-warning "shadows a parameter" }
+ void f(int infoo) { } // { dg-bogus "shadows a parameter" }
};
return outfoo;
}
// PR c++/39763
int foo2(void)
{
- int infoo = 0; // { dg-warning "shadowed declaration" }
+ int infoo = 0; // { dg-bogus "shadowed declaration" }
int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" }
struct A
{
- void f(int infoo) { } // { dg-warning "shadows a previous local" }
+ void f(int infoo) { } // { dg-bogus "shadows a previous local" }
};
return outfoo;
}
--- /dev/null
+// Test the declaration of nested lambda function shadows
+// a parameter or previous local.
+// { dg-do compile }
+// { dg-options "-std=c++0x -Wshadow" }
+
+struct S {};
+int f1(int x) // { dg-warning "shadowed declaration" }
+{
+ int t = 0;
+ int m = 0; // { dg-warning "shadowed declaration" }
+ [&t] (int x) { // { dg-warning "shadows a parameter" }
+ int m = 1; // { dg-warning "shadows a previous local" }
+ t = t + x + m;
+ };
+ return t;
+}
+
+void f2(struct S i, int j) {
+ struct A {
+ struct S x;
+ void g(struct S i) { // { dg-warning "shadowed declaration" }
+ struct S x; // { dg-warning "shadows a member of" }
+ struct S y; // { dg-warning "shadowed declaration" }
+ int t;
+ [&t](struct S i){ // { dg-warning "shadows a parameter" }
+ int j = 1; // { dg-bogus "shadows" }
+ struct S y; // { dg-warning "shadows a previous local" }
+ t = j;
+ };
+ }
+ };
+}
+
+void f3(int i) {
+ [=]{
+ int j = i;
+ int i; // { dg-warning "shadows a member of" }
+ };
+}