diff mbox

C++ PATCH for c++/44587 (qualified-ids as template arguments)

Message ID 4C2A4936.20202@redhat.com
State New
Headers show

Commit Message

Jason Merrill June 29, 2010, 7:27 p.m. UTC
While I was working on that, I noticed some other oddities:

1) We were using the same function to test type- and value- dependency 
of a qualified-id (SCOPE_REF), but the rules in the standard are different.

2) Fixing that exposed a case where we weren't setting the type of a 
SCOPE_REF properly.

3) We want to call mark_lvalue_use in convert_nontype_argument if the 
parameter is a reference.

Tested x86_64-pc-linux-gnu, applied to trunk.
diff mbox

Patch

commit 62839c575601f53cd57bdfb0ec897fd40256e113
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jun 29 10:43:03 2010 -0400

    	* pt.c (dependent_scope_ref_p): Remove.
    	(value_dependent_expression_p): Don't call it.
    	(type_dependent_expression_p): Here either.
    	* init.c (build_offset_ref): Set TREE_TYPE on a qualified-id
    	if the scope isn't dependent.
    
    	* pt.c (convert_nontype_argument): Use mark_lvalue_use if we want
    	a reference.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 30808b2..7df57ab 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1508,8 +1508,17 @@  build_offset_ref (tree type, tree member, bool address_p)
     return member;
 
   if (dependent_type_p (type) || type_dependent_expression_p (member))
-    return build_qualified_name (NULL_TREE, type, member,
-				 /*template_p=*/false);
+    {
+      tree ref, mem_type = NULL_TREE;
+      if (!dependent_scope_p (type))
+	mem_type = TREE_TYPE (member);
+      ref = build_qualified_name (mem_type, type, member,
+				  /*template_p=*/false);
+      /* Undo convert_from_reference.  */
+      if (TREE_CODE (ref) == INDIRECT_REF)
+	ref = TREE_OPERAND (ref, 0);
+      return ref;
+    }
 
   gcc_assert (TYPE_P (type));
   if (! is_class_type (type, 1))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8a447ec..e4b57db 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4968,7 +4968,10 @@  convert_nontype_argument (tree type, tree expr)
   if (error_operand_p (expr))
     return error_mark_node;
   expr_type = TREE_TYPE (expr);
-  expr = mark_rvalue_use (expr);
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    expr = mark_lvalue_use (expr);
+  else
+    expr = mark_rvalue_use (expr);
 
   /* HACK: Due to double coercion, we can get a
      NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
@@ -17517,40 +17520,6 @@  dependent_scope_p (tree scope)
 	  && !currently_open_class (scope));
 }
 
-/* Returns TRUE if EXPRESSION is dependent, according to CRITERION.  */
-
-static bool
-dependent_scope_ref_p (tree expression, bool criterion (tree))
-{
-  tree scope;
-  tree name;
-
-  gcc_assert (TREE_CODE (expression) == SCOPE_REF);
-
-  if (!TYPE_P (TREE_OPERAND (expression, 0)))
-    return true;
-
-  scope = TREE_OPERAND (expression, 0);
-  name = TREE_OPERAND (expression, 1);
-
-  /* [temp.dep.expr]
-
-     An id-expression is type-dependent if it contains a
-     nested-name-specifier that contains a class-name that names a
-     dependent type.  */
-  /* The suggested resolution to Core Issue 224 implies that if the
-     qualifying type is the current class, then we must peek
-     inside it.  */
-  if (DECL_P (name)
-      && currently_open_class (scope)
-      && !criterion (name))
-    return false;
-  if (dependent_type_p (scope))
-    return true;
-
-  return false;
-}
-
 /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
    [temp.dep.constexpr].  EXPRESSION is already known to be a constant
    expression.  */
@@ -17640,7 +17609,10 @@  value_dependent_expression_p (tree expression)
 	      || value_dependent_expression_p (expression));
 
     case SCOPE_REF:
-      return dependent_scope_ref_p (expression, value_dependent_expression_p);
+      {
+	tree name = TREE_OPERAND (expression, 1);
+	return value_dependent_expression_p (name);
+      }
 
     case COMPONENT_REF:
       return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
@@ -17783,10 +17755,19 @@  type_dependent_expression_p (tree expression)
 	return dependent_type_p (type);
     }
 
-  if (TREE_CODE (expression) == SCOPE_REF
-      && dependent_scope_ref_p (expression,
-				type_dependent_expression_p))
-    return true;
+  if (TREE_CODE (expression) == SCOPE_REF)
+    {
+      tree scope = TREE_OPERAND (expression, 0);
+      tree name = TREE_OPERAND (expression, 1);
+
+      /* 14.6.2.2 [temp.dep.expr]: An id-expression is type-dependent if it
+	 contains an identifier associated by name lookup with one or more
+	 declarations declared with a dependent type, or...a
+	 nested-name-specifier or qualified-id that names a member of an
+	 unknown specialization.  */
+      return (type_dependent_expression_p (name)
+	      || dependent_scope_p (scope));
+    }
 
   if (TREE_CODE (expression) == FUNCTION_DECL
       && DECL_LANG_SPECIFIC (expression)