[patch] Fix g++.dg/gomp/{pr27325.C,pr27337-2.C}.

Kazu Hirata kazu@codesourcery.com
Wed Aug 15 00:03:00 GMT 2007


Hi,

Attached is a patch to fix g++.dg/gomp/{pr27325.C,pr27337-2.C}.

These testcases crash in get_callee_fndecl called from
finish_omp_clauses.  Here is a quote from Mark.

  "It's trying to figure out what constructor/destructor would be called,
  by generating a call to it.  Then, it squirrels that information
  away and calls the function by hand elsewhere.  This is gross, but
  to do better would require setting up an alternative interface to
  build_special_member_call which did most of the work that this code
  does, and then returned the FUNCTION_DECL.  That's too hard, so
  let's just continue the hack.

  The crash happens at get_callee_fndecl.  That function takes a tree,
  which should be a call, and tries to figure out what function is
  being called.  But, on ARM, the tree is not actually a CALL_EXPR;
  it's a NOP_EXPR.  That's because on ARM constructors and destructors
  return "this" (the ABI requires that), so the front end has cast the
  result of the call to "void" (since that's what we have on other
  platforms)."

The patch fixes the problem by stripping a NOP_EXPR.  I wanted to use
STRIP_NOPS, but I couldn't for the reason stated in the comment.

Tested on arm-none-linux-gnueabi.  Committed as preapproved in private
communication.

Kazu Hirata

2007-08-14  Mark Mitchell  <mark@codesourcery.com>

	* semantics.c (finish_omp_clauses): Strip a NOP_EXPR if
	constructors and destructors return this.

Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 178959)
+++ gcc/cp/semantics.c	(working copy)
@@ -3626,6 +3626,17 @@ finish_omp_clauses (tree clauses)
 	      t = build_special_member_call (NULL_TREE,
 					     complete_ctor_identifier,
 					     t, inner_type, LOOKUP_NORMAL);
+
+	      if (targetm.cxx.cdtor_returns_this ())
+		/* Because constructors and destructors return this,
+		   the call will have been cast to "void".  Remove the
+		   cast here.  We would like to use STRIP_NOPS, but it
+		   wouldn't work here because TYPE_MODE (t) and
+		   TYPE_MODE (TREE_OPERAND (t, 0)) are different.
+		   They are VOIDmode and Pmode, respectively.  */
+		if (TREE_CODE (t) == NOP_EXPR)
+		  t = TREE_OPERAND (t, 0);
+
 	      t = get_callee_fndecl (t);
 	      TREE_VEC_ELT (info, 0) = t;
 	    }
@@ -3637,6 +3648,17 @@ finish_omp_clauses (tree clauses)
 	      t = build1 (INDIRECT_REF, inner_type, t);
 	      t = build_special_member_call (t, complete_dtor_identifier,
 					     NULL, inner_type, LOOKUP_NORMAL);
+
+	      if (targetm.cxx.cdtor_returns_this ())
+		/* Because constructors and destructors return this,
+		   the call will have been cast to "void".  Remove the
+		   cast here.  We would like to use STRIP_NOPS, but it
+		   wouldn't work here because TYPE_MODE (t) and
+		   TYPE_MODE (TREE_OPERAND (t, 0)) are different.
+		   They are VOIDmode and Pmode, respectively.  */
+		if (TREE_CODE (t) == NOP_EXPR)
+		  t = TREE_OPERAND (t, 0);
+
 	      t = get_callee_fndecl (t);
 	      TREE_VEC_ELT (info, 1) = t;
 	    }



More information about the Gcc-patches mailing list