Patchwork C++ PATCH to enable checking with aggressive GC tuning

login
register
mail settings
Submitter Jason Merrill
Date July 16, 2011, 4:09 a.m.
Message ID <4E210EE0.9090206@redhat.com>
Download mbox | patch
Permalink /patch/104929/
State New
Headers show

Comments

Jason Merrill - July 16, 2011, 4:09 a.m.
This patch adds 'make check-g++-strict-gc' for running the C++ testsuite 
with aggressive GC tuning for catching GC issues that might otherwise 
lie undetected for a while.  And it fixes several current issues that I 
found using it: the GTY markings I had put in except.c had no effect 
because I hadn't added it to the list of files to scan, and we can't GC 
after a function (lambda or template instantiation) in the middle of an 
expression.

I'm not adding this to any other targets, as some current tests take a 
very long time to run in this mode.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 20bdb0b4a32912673c5802dc3803434547165faf
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jul 15 10:59:31 2011 -0400

    	* Make-lang.in (check-g++-strict-gc): New.
    	(cp/except.o): Depend on gt-cp-except.h
    	* except.c: Include gt-cp-except.h.
    	* config-lang.in (gtfiles): Add cp/except.c.
    	* decl2.c (mark_used): Adjust constexpr condition, set
    	function_depth around template instantiation.
    	* parser.c (cp_parser_lambda_body): Set function_depth.
    	* semantics.c (maybe_add_lambda_conv_op): Likewise.

diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index ad466b2..21145b2 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -153,6 +153,10 @@  check-c++ : check-g++
 check-c++0x:
 	$(MAKE) RUNTESTFLAGS="$(RUNTESTFLAGS) --extra_opts,-std=gnu++0x" \
 	  TESTSUITEDIR="$(TESTSUITEDIR).c++0x" check-g++
+# Run the testsuite with garbage collection at every opportunity.
+check-g++-strict-gc:
+	$(MAKE) RUNTESTFLAGS="$(RUNTESTFLAGS) --extra_opts,--param,ggc-min-heapsize=0,--param,ggc-min-expand=0" \
+	  TESTSUITEDIR="$(TESTSUITEDIR).gc" check-g++
 check-c++-subtargets : check-g++-subtargets
 # List of targets that can use the generic check- rule and its // variant.
 lang_checks += check-g++
@@ -309,7 +313,7 @@  cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
 cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) convert.h \
   $(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h intl.h
 cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
-  cp/cfns.h $(TREE_INLINE_H) $(TARGET_H)
+  cp/cfns.h $(TREE_INLINE_H) $(TARGET_H) gt-cp-except.h
 cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(TM_P_H)
 cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
   toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h vecprim.h intl.h \
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 13f2e9c..3ed3d8e 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -30,4 +30,4 @@  compilers="cc1plus\$(exeext)"
 
 target_libs="target-libstdc++-v3"
 
-gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c"
+gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c"
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e1f9562..f05b0f8 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4231,9 +4231,9 @@  mark_used (tree decl)
   if ((decl_maybe_constant_var_p (decl)
        || (TREE_CODE (decl) == FUNCTION_DECL
 	   && DECL_DECLARED_CONSTEXPR_P (decl)))
-      && !DECL_INITIAL (decl)
       && DECL_LANG_SPECIFIC (decl)
-      && DECL_TEMPLATE_INSTANTIATION (decl))
+      && DECL_TEMPLATE_INFO (decl)
+      && !uses_template_parms (DECL_TI_ARGS (decl)))
     {
       /* Instantiating a function will result in garbage collection.  We
 	 must treat this situation as if we were within the body of a
@@ -4327,8 +4327,12 @@  mark_used (tree decl)
        times.  Maintaining a stack of active functions is expensive,
        and the inliner knows to instantiate any functions it might
        need.  Therefore, we always try to defer instantiation.  */
-    instantiate_decl (decl, /*defer_ok=*/true,
-		      /*expl_inst_class_mem_p=*/false);
+    {
+      ++function_depth;
+      instantiate_decl (decl, /*defer_ok=*/true,
+			/*expl_inst_class_mem_p=*/false);
+      --function_depth;
+    }
 }
 
 #include "gt-cp-decl2.h"
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index f8c8e47..c37815d 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1227,3 +1227,5 @@  build_noexcept_spec (tree expr, int complain)
       return build_tree_list (expr, NULL_TREE);
     }
 }
+
+#include "gt-cp-except.h"
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 64be923..5fcedcd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7737,6 +7737,10 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
   bool nested = (current_function_decl != NULL_TREE);
   if (nested)
     push_function_context ();
+  else
+    /* Still increment function_depth so that we don't GC in the
+       middle of an expression.  */
+    ++function_depth;
 
   /* Finish the function call operator
      - class_specifier
@@ -7836,6 +7840,8 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
 
   if (nested)
     pop_function_context();
+  else
+    --function_depth;
 }
 
 /* Statements [gram.stmt.stmt]  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fadef4d..fdd6c33 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8875,6 +8875,10 @@  maybe_add_lambda_conv_op (tree type)
 
   if (nested)
     push_function_context ();
+  else
+    /* Still increment function_depth so that we don't GC in the
+       middle of an expression.  */
+    ++function_depth;
 
   /* Generate the body of the thunk.  */
 
@@ -8927,6 +8931,8 @@  maybe_add_lambda_conv_op (tree type)
 
   if (nested)
     pop_function_context ();
+  else
+    --function_depth;
 }
 
 /* Returns true iff VAL is a lambda-related declaration which should