From patchwork Tue Jun 29 19:27:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/44587 (qualified-ids as template arguments) Date: Tue, 29 Jun 2010 09:27:50 -0000 From: Jason Merrill X-Patchwork-Id: 57307 Message-Id: <4C2A4936.20202@redhat.com> To: gcc-patches List 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. commit 62839c575601f53cd57bdfb0ec897fd40256e113 Author: Jason Merrill 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(ADDR_EXPR (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)