[PATCH][RFC] C++ error for parameter redefinition in function prototypes

Simon Baldwin simonb@google.com
Thu Mar 29 20:08:00 GMT 2007


Attached is a proposed small patch to add an error report for function
prototypes that specify duplicate parameter names.

Making this an error rather than a warning matches the behavior of gcc under
similar circumstances.  It could be downgraded to a warning, though, if the
consensus opinion is that an error is too strict.

There is a new test in the testsuite for this error.  One of the existing
tests also generated the warning: cpp0x/variadic-ex9.C.  This test is modified
slightly so that it no longer triggers the error.


gcc/cp/ChangeLog
2007-03-29  Simon Baldwin <simonb@google.com>

	* decl.c (grokparms): Added new error for duplicate function
	parameters names in function prototypes, to match gcc behavior.

gcc/testsuite/ChangeLog
2007-03-29  Simon Baldwin <simonb@google.com>

	* g++.dg/other/error15.C: New.
	* g++.dg/cpp0x/variadic-ex9.C: Renamed function parameter to avoid
	triggering a "redefinition of parameter" error.


diff -Nrcp3 gcc-4.3-20070323_orig/gcc/cp/decl.c gcc-4.3-20070323_new/gcc/cp/decl.c
*** gcc-4.3-20070323_orig/gcc/cp/decl.c	Thu Mar 15 15:24:42 2007
--- gcc-4.3-20070323_new/gcc/cp/decl.c	Thu Mar 29 09:48:44 2007
*************** grokparms (cp_parameter_declarator *firs
*** 8957,8962 ****
--- 8957,8980 ----
        TREE_CHAIN (decl) = decls;
        decls = decl;
        result = tree_cons (init, type, result);
+ 
+       /* Search the list for any existing parameters with a name that
+          duplicates the name of the parameter just parsed.  */
+       if (DECL_NAME (decls))
+         {
+           const char *const name = IDENTIFIER_POINTER (DECL_NAME (decls));
+ 
+           for (decl = TREE_CHAIN (decls); decl; decl = TREE_CHAIN (decl))
+             {
+               if (DECL_NAME (decl)
+                   && strcmp (name,
+                              IDENTIFIER_POINTER (DECL_NAME (decl))) == 0)
+                 {
+                   error ("redefinition of parameter %qD", decls);
+                   break;
+                 }
+             }
+         }
      }
    decls = nreverse (decls);
    result = nreverse (result);
diff -Nrcp3 gcc-4.3-20070323_orig/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C gcc-4.3-20070323_new/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C
*** gcc-4.3-20070323_orig/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C	Fri Mar  9 18:01:49 2007
--- gcc-4.3-20070323_new/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C	Thu Mar 29 09:56:27 2007
***************
*** 1,7 ****
  // { dg-options "-std=gnu++0x" }
  template<typename... Args>              char& f(Args... args);         // #1
  template<typename T1, typename... Args> short& f(T1 a1, Args... args); // #2
! template<typename T1, typename T2>      int& f(T1 a2, T2 a2);          // #3
  
  void g() {
    char& x = f();                      // calls #1
--- 1,7 ----
  // { dg-options "-std=gnu++0x" }
  template<typename... Args>              char& f(Args... args);         // #1
  template<typename T1, typename... Args> short& f(T1 a1, Args... args); // #2
! template<typename T1, typename T2>      int& f(T1 a2, T2 a3);          // #3
  
  void g() {
    char& x = f();                      // calls #1
diff -Nrcp3 gcc-4.3-20070323_orig/gcc/testsuite/g++.dg/other/error15.C gcc-4.3-20070323_new/gcc/testsuite/g++.dg/other/error15.C
*** gcc-4.3-20070323_orig/gcc/testsuite/g++.dg/other/error15.C	Wed Dec 31 16:00:00 1969
--- gcc-4.3-20070323_new/gcc/testsuite/g++.dg/other/error15.C	Thu Mar 29 12:08:28 2007
***************
*** 0 ****
--- 1,60 ----
+ // Test that duplicate function parameters are found in declarations.
+ 
+ extern void g0 (int a, int b);
+ extern void g1 (int a, float b);
+ 
+ extern void f0 (int a,
+                 int a);  // { dg-error "redefinition of parameter 'a'" }
+ extern void f1 (int a,
+                 float a);  // { dg-error "redefinition of parameter 'a'" }
+ extern void f3 (int a, int b, int c,
+                 int a);  // { dg-error "redefinition of parameter 'a'" }
+ extern void f4 (int a, int b, int c,
+                 int a,
+                 int a);  // { dg-error "redefinition of parameter 'a'" }
+ extern void f5 (int a, int b, int c, int d, int e, int f, int g, int h,
+                 int a,
+                 int i, int j, int k, int l, int m, int n, int o, int p,
+                 int q, int r, int s, int t, int u, int v, int w, int x, int y,
+                 int z);  // { dg-error "redefinition of parameter 'a'" }
+ 
+ extern void f6 (int a, int, int, int, int, int, int, int, int, int, int,
+                 int a,
+                 int, int, int, int, int, int, int, int, int, int, int,
+                 float, float, float, float, float, float, float, float,
+                 int);  // { dg-error "redefinition of parameter 'a'" }
+ 
+ extern void f7 (void (*a)(int),
+                 void (*a)(int));  // { dg-error "redefinition of parameter 'a'" }
+ extern void f8 (float (*a)(int),
+                 int (*a)(float));  // { dg-error "redefinition of parameter 'a'" }
+ 
+ extern void f9 (int a,
+                 int a,
+                 int a);
+ // { dg-error "redefinition of parameter 'a'" "" { target *-*-* } 34 }
+ 
+ extern void f10 (int a,
+                  int b,
+                  int c,
+                  int c,
+                  int b,
+                  int a);
+ // { dg-error "redefinition of parameter 'a'" "" { target *-*-* } 42 }
+ // { dg-error "redefinition of parameter 'b'" "" { target *-*-* } 42 }
+ // { dg-error "redefinition of parameter 'c'" "" { target *-*-* } 42 }
+ 
+ class C1 {
+  public:
+   void C1_g0 (int a, int b);
+   void C1_f0 (int a,
+               int a);  // { dg-error "redefinition of parameter 'a'" }
+ };
+ 
+ template <class T>
+ class C2 {
+  public:
+   void C2_g0 (T a, T b);
+   void C2_f0 (T a,
+               T a);  // { dg-error "redefinition of parameter 'a'" }
+ };



More information about the Gcc-patches mailing list