diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/init.c | 25 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 16 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/sfinae45.C | 35 |
8 files changed, 81 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e41a079..1f37496 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2013-04-24 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/56970 + * init.c (build_offset_ref): Add tsubst_flags_t parameter. + * semantics.c (finish_qualified_id_expr): Likewise. + (finish_id_expression): Update. + * typeck.c (cp_build_addr_expr_1): Likewise. + * pt.c (tsubst_qualified_id, resolve_nondeduced_context): Likewise. + * cp-tree.h: Update declarations. + 2013-04-22 Jason Merrill <jason@redhat.com> Core 1586 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d96340a..339892e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5351,7 +5351,8 @@ extern tree get_type_value (tree); extern tree build_zero_init (tree, tree, bool); extern tree build_value_init (tree, tsubst_flags_t); extern tree build_value_init_noctor (tree, tsubst_flags_t); -extern tree build_offset_ref (tree, tree, bool); +extern tree build_offset_ref (tree, tree, bool, + tsubst_flags_t); extern tree build_new (vec<tree, va_gc> **, tree, tree, vec<tree, va_gc> **, int, tsubst_flags_t); @@ -5748,7 +5749,7 @@ extern void add_typedef_to_current_template_for_access_check (tree, tree, location_t); extern void check_accessibility_of_qualified_id (tree, tree, tree); extern tree finish_qualified_id_expr (tree, tree, bool, bool, - bool, bool); + bool, bool, tsubst_flags_t); extern void simplify_aggr_init_expr (tree *); extern void finalize_nrv (tree *, tree, tree); extern void note_decl_for_pch (tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 7b7de02..28e2555 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1817,7 +1817,8 @@ get_type_value (tree name) @@ This function should be rewritten and placed in search.c. */ tree -build_offset_ref (tree type, tree member, bool address_p) +build_offset_ref (tree type, tree member, bool address_p, + tsubst_flags_t complain) { tree decl; tree basebinfo = NULL_TREE; @@ -1841,7 +1842,8 @@ build_offset_ref (tree type, tree member, bool address_p) type = TYPE_MAIN_VARIANT (type); if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type))) { - error ("incomplete type %qT does not have member %qD", type, member); + if (complain & tf_error) + error ("incomplete type %qT does not have member %qD", type, member); return error_mark_node; } @@ -1854,7 +1856,8 @@ build_offset_ref (tree type, tree member, bool address_p) if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member)) { - error ("invalid pointer to bit-field %qD", member); + if (complain & tf_error) + error ("invalid pointer to bit-field %qD", member); return error_mark_node; } @@ -1883,10 +1886,10 @@ build_offset_ref (tree type, tree member, bool address_p) if (address_p && DECL_P (t) && DECL_NONSTATIC_MEMBER_P (t)) perform_or_defer_access_check (TYPE_BINFO (type), t, t, - tf_warning_or_error); + complain); else perform_or_defer_access_check (basebinfo, t, t, - tf_warning_or_error); + complain); if (DECL_STATIC_FUNCTION_P (t)) return t; @@ -1900,7 +1903,7 @@ build_offset_ref (tree type, tree member, bool address_p) check_accessibility_of_qualified_id in case it is a pointer to non-static member. */ perform_or_defer_access_check (TYPE_BINFO (type), member, member, - tf_warning_or_error); + complain); if (!address_p) { @@ -1932,15 +1935,17 @@ build_offset_ref (tree type, tree member, bool address_p) if (flag_ms_extensions) { PTRMEM_OK_P (member) = 1; - return cp_build_addr_expr (member, tf_warning_or_error); + return cp_build_addr_expr (member, complain); } - error ("invalid use of non-static member function %qD", - TREE_OPERAND (member, 1)); + if (complain & tf_error) + error ("invalid use of non-static member function %qD", + TREE_OPERAND (member, 1)); return error_mark_node; } else if (TREE_CODE (member) == FIELD_DECL) { - error ("invalid use of non-static data member %qD", member); + if (complain & tf_error) + error ("invalid use of non-static data member %qD", member); return error_mark_node; } return member; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 855c1f7..7d169b76 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12053,7 +12053,7 @@ tsubst_qualified_id (tree qualified_id, tree args, expr = (finish_qualified_id_expr (scope, expr, done, address_p && PTRMEM_OK_P (qualified_id), QUALIFIED_NAME_IS_TEMPLATE (qualified_id), - /*template_arg_p=*/false)); + /*template_arg_p=*/false, complain)); } /* Expressions do not generally have reference type. */ @@ -16040,7 +16040,7 @@ resolve_nondeduced_context (tree orig_expr) { tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0))); - expr = build_offset_ref (base, expr, addr); + expr = build_offset_ref (base, expr, addr, tf_warning_or_error); } if (addr) expr = cp_build_addr_expr (expr, tf_warning_or_error); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d4f0f82..5c0fc72 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1772,7 +1772,8 @@ finish_qualified_id_expr (tree qualifying_class, bool done, bool address_p, bool template_p, - bool template_arg_p) + bool template_arg_p, + tsubst_flags_t complain) { gcc_assert (TYPE_P (qualifying_class)); @@ -1792,7 +1793,7 @@ finish_qualified_id_expr (tree qualifying_class, if (TREE_CODE (expr) == SCOPE_REF) expr = TREE_OPERAND (expr, 1); expr = build_offset_ref (qualifying_class, expr, - /*address_p=*/true); + /*address_p=*/true, complain); return expr; } @@ -1826,11 +1827,12 @@ finish_qualified_id_expr (tree qualifying_class, expr, BASELINK_ACCESS_BINFO (expr), /*preserve_reference=*/false, - tf_warning_or_error)); + complain)); else if (done) /* The expression is a qualified name whose address is not being taken. */ - expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false); + expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false, + complain); } else if (BASELINK_P (expr)) ; @@ -3278,7 +3280,8 @@ finish_id_expression (tree id_expression, decl = finish_qualified_id_expr (scope, decl, done, address_p, template_p, - template_arg_p); + template_arg_p, + tf_warning_or_error); else { tree type = NULL_TREE; @@ -3394,7 +3397,8 @@ finish_id_expression (tree id_expression, done, address_p, template_p, - template_arg_p); + template_arg_p, + tf_warning_or_error); else decl = convert_from_reference (decl); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c0696e0..b45b685 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5164,7 +5164,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) " Say %<&%T::%D%>", base, name); } - arg = build_offset_ref (base, fn, /*address_p=*/true); + arg = build_offset_ref (base, fn, /*address_p=*/true, complain); } /* Uninstantiated types are all functions. Taking the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5d3ff3..7be7560 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-24 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/56970 + * g++.dg/cpp0x/sfinae45.C: New. + 2013-04-24 Richard Biener <rguenther@suse.de> PR testsuite/57050 diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae45.C b/gcc/testsuite/g++.dg/cpp0x/sfinae45.C new file mode 100644 index 0000000..bd37514 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae45.C @@ -0,0 +1,35 @@ +// PR c++/56970 +// { dg-do compile { target c++11 } } + +template <typename T> +struct has +{ + template <typename> + constexpr static int test(...) { + return 0; + } + + template <typename C> + constexpr static int test(decltype(sizeof(C::x))) { // Doesn't compile. + return 1; // Is a member variable. + } + + template <typename C, int c = sizeof(decltype(((C*)nullptr)->x()))> + constexpr static int test(int) { + return 2; // Is a member function. + } + + static const int value = test<T>(0); +}; + +struct foo { + int x; +}; + +struct bar { + int x(); +}; + +static_assert(has<int>::value == 0, ""); +static_assert(has<foo>::value == 1, ""); +static_assert(has<bar>::value == 2, ""); |