sepavloff created this revision.
sepavloff added a subscriber: cfe-commits.

If definition of default function argument uses itself, clang crashed,
because corresponding function parameter is not associated with the default
argument yet. With this fix clang emits appropriate error message.

This change fixes PR28105.

http://reviews.llvm.org/D21301

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExpr.cpp
  test/SemaCXX/default2.cpp

Index: test/SemaCXX/default2.cpp
===================================================================
--- test/SemaCXX/default2.cpp
+++ test/SemaCXX/default2.cpp
@@ -128,3 +128,7 @@
 
 template <int I1 = I2, int I2 = 1> struct T {};  // expected-error-re {{use of 
undeclared identifier 'I2'{{$}}}}
 T<0, 1> t;
+
+struct PR28105 {
+  PR28105 (int = 0, int = 0, PR28105 = 0);  // expected-error{{recursive 
evaluation of default argument}}
+};
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -4566,6 +4566,13 @@
     }
   }
 
+  // If the default argument expression is not set yet, we are building it now.
+  if (!Param->getInit()) {
+    Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
+    Param->setInvalidDecl();
+    return ExprError();
+  }
+
   // If the default expression creates temporaries, we need to
   // push them to the current stack of expression temporaries so they'll
   // be properly destroyed.
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3107,6 +3107,7 @@
   "use of default argument to function %0 that is declared later in class %1">;
 def note_default_argument_declared_here : Note<
   "default argument declared here">;
+def err_recursive_default_argument : Error<"recursive evaluation of default 
argument">;
 
 def ext_param_promoted_not_compatible_with_prototype : ExtWarn<
   "%diff{promoted type $ of K&R function parameter is not compatible with the "


Index: test/SemaCXX/default2.cpp
===================================================================
--- test/SemaCXX/default2.cpp
+++ test/SemaCXX/default2.cpp
@@ -128,3 +128,7 @@
 
 template <int I1 = I2, int I2 = 1> struct T {};  // expected-error-re {{use of undeclared identifier 'I2'{{$}}}}
 T<0, 1> t;
+
+struct PR28105 {
+  PR28105 (int = 0, int = 0, PR28105 = 0);  // expected-error{{recursive evaluation of default argument}}
+};
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -4566,6 +4566,13 @@
     }
   }
 
+  // If the default argument expression is not set yet, we are building it now.
+  if (!Param->getInit()) {
+    Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
+    Param->setInvalidDecl();
+    return ExprError();
+  }
+
   // If the default expression creates temporaries, we need to
   // push them to the current stack of expression temporaries so they'll
   // be properly destroyed.
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3107,6 +3107,7 @@
   "use of default argument to function %0 that is declared later in class %1">;
 def note_default_argument_declared_here : Note<
   "default argument declared here">;
+def err_recursive_default_argument : Error<"recursive evaluation of default argument">;
 
 def ext_param_promoted_not_compatible_with_prototype : ExtWarn<
   "%diff{promoted type $ of K&R function parameter is not compatible with the "
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to