GCC warns for class members that are initialized with themselves,
and with c++/64667 fixed, this includes references.

Unfortunately, the diagnostic that's printed is inconsistent between
pointers and references, and other members. For the first two kinds,
it's missing the caret, and for others it points to the ctor rather
than to the member-initializer (see bellow).

The attached patch fixes it so that all such diagnostics consistently
point to the member-initializer, and adds a test to verify gcc does
so.

Martin

struct S {
    int m;
    int &r;
    int *p;
    S ():
    m (m),
    r (r),
    p (p)
    { }
};
u.cpp: In constructor ‘S::S()’:
u.cpp:5:5: warning: ‘S::m’ is initialized with itself [-Winit-self]
     S ():
     ^

u.cpp:5:5: warning: ‘S::r’ is initialized with itself [-Winit-self]
u.cpp:5:5: warning: ‘S::p’ is initialized with itself [-Winit-self]
gcc/cp/
2015-11-11  Martin Sebor  <mse...@redhat.com>

	PR c++/68208
	* init.c (perform_member_init): Use location of member-initializer
	in -Wself-init rather than that of the ctor.

gcc/testsuite/
2015-11-11  Martin Sebor  <mse...@redhat.com>

	PR c++/68208
	* b/gcc/testsuite/g++.dg/warn/Winit-self-4.C: New test.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 2e11acb..055e9d9 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -638,7 +638,7 @@ perform_member_init (tree member, tree init)
 	val = TREE_OPERAND (val, 0);
       if (TREE_CODE (val) == COMPONENT_REF && TREE_OPERAND (val, 1) == member
 	  && TREE_OPERAND (val, 0) == current_class_ref)
-	warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+	warning_at (EXPR_LOC_OR_LOC (val, input_location),
 		    OPT_Winit_self, "%qD is initialized with itself",
 		    member);
     }
diff --git a/gcc/testsuite/g++.dg/warn/Winit-self-4.C b/gcc/testsuite/g++.dg/warn/Winit-self-4.C
new file mode 100644
index 0000000..0e61abf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Winit-self-4.C
@@ -0,0 +1,16 @@
+// PR c++/68208
+// { dg-options "-Winit-self" }
+
+// Verify that -Winit-self warning issued for reference and pointer
+// members points to the member-initializer and not to the constructor.
+struct S
+{
+    int i;
+    int *p;
+    int &r;
+    S ():
+        i (i),    // { dg-warning "initialized with itself" }
+        p (p),    // { dg-warning "initialized with itself" }
+        r (r)     // { dg-warning "initialized with itself" }
+        { }
+};

Reply via email to