diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index 9b746be231ae34ccd0664deaf5a14be091d780c8..da0a65c613d3b07787034bcc95b33e19894d6268 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -1253,7 +1253,7 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain) if (check_for_bare_parameter_packs (expr)) return error_mark_node; if (TREE_CODE (expr) != DEFERRED_NOEXCEPT - && !value_dependent_expression_p (expr)) + && !instantiation_dependent_expression_p (expr)) { expr = build_converted_constant_bool_expr (expr, complain); expr = instantiate_non_dependent_expr_sfinae (expr, complain); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9153c74f0694de2ddf3053da6966c2492a80992d..5c342ca631b371ce5762133cd1eda259f746ebc3 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -7958,7 +7958,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, static cp_expr cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p, bool allow_expansion_p, - bool fold_expr_p, bool *non_constant_p) { cp_expr expr (NULL_TREE); @@ -7985,9 +7984,6 @@ cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p, else expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p); - if (fold_expr_p) - expr = instantiate_non_dependent_expr (expr); - /* If we have an ellipsis, then this is an expression expansion. */ if (allow_expansion_p && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -8053,8 +8049,6 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, false, /*allow_exp_p=*/ true, - /*fold_expr_p=*/ - false, /*non_cst_p=*/ NULL); @@ -8424,7 +8418,6 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, bool wrap_locations_p) { vec<tree, va_gc> *expression_list; - bool fold_expr_p = is_attribute_list != non_attr; tree identifier = NULL_TREE; bool saved_greater_than_is_operator_p; @@ -8467,7 +8460,6 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, expr = cp_parser_parenthesized_expression_list_elt (parser, cast_p, allow_expansion_p, - fold_expr_p, non_constant_p); if (wrap_locations_p) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f8069b2ea0ebace2a6dcd9d388f103c419ebeb87..f7ee33a6dfd130e8c556abd436dc54c354de9210 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -3817,7 +3817,7 @@ expand_integer_pack (tree call, tree args, tsubst_flags_t complain, tree hi = tsubst_copy_and_build (ohi, args, complain, in_decl, false/*fn*/, true/*int_cst*/); - if (value_dependent_expression_p (hi)) + if (instantiation_dependent_expression_p (hi)) { if (hi != ohi) { @@ -6349,9 +6349,7 @@ redeclare_class_template (tree type, tree parms, tree cons) /* The actual substitution part of instantiate_non_dependent_expr_sfinae, to be used when the caller has already checked - (processing_template_decl - && !instantiation_dependent_expression_p (expr) - && potential_constant_expression (expr)) + !instantiation_dependent_uneval_expression_p (expr) and cleared processing_template_decl. */ tree @@ -6365,8 +6363,7 @@ instantiate_non_dependent_expr_internal (tree expr, tsubst_flags_t complain) /*integral_constant_expression_p=*/true); } -/* Simplify EXPR if it is a non-dependent expression. Returns the - (possibly simplified) expression. */ +/* Instantiate the non-dependent expression EXPR. */ tree instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) @@ -6374,16 +6371,10 @@ instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) if (expr == NULL_TREE) return NULL_TREE; - /* If we're in a template, but EXPR isn't value dependent, simplify - it. We're supposed to treat: - - template <typename T> void f(T[1 + 1]); - template <typename T> void f(T[2]); - - as two declarations of the same function, for example. */ - if (processing_template_decl - && is_nondependent_constant_expression (expr)) + if (processing_template_decl) { + /* The caller should have checked this already. */ + gcc_checking_assert (!instantiation_dependent_uneval_expression_p (expr)); processing_template_decl_sentinel s; expr = instantiate_non_dependent_expr_internal (expr, complain); } @@ -6396,8 +6387,8 @@ instantiate_non_dependent_expr (tree expr) return instantiate_non_dependent_expr_sfinae (expr, tf_error); } -/* Like instantiate_non_dependent_expr, but return NULL_TREE rather than - an uninstantiated expression. */ +/* Like instantiate_non_dependent_expr, but return NULL_TREE if the + expression is dependent or non-constant. */ tree instantiate_non_dependent_or_null (tree expr) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index a2c0eb050e649416bc75d601e502b04011ee2867..799ce943279f976d42cc4c3b6611a5d50f6aaec9 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -11217,6 +11217,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, /* decltype is an unevaluated context. */ cp_unevaluated u; + processing_template_decl_sentinel ptds (/*reset=*/false); + /* Depending on the resolution of DR 1172, we may later need to distinguish instantiation-dependent but not type-dependent expressions so that, say, A<decltype(sizeof(T))>::U doesn't require 'typename'. */ @@ -11235,6 +11237,10 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, expr = instantiate_non_dependent_expr_sfinae (expr, complain); if (expr == error_mark_node) return error_mark_node; + /* Keep processing_template_decl cleared for the rest of the function + (for sake of the call to lvalue_kind below, which handles templated + and non-templated COND_EXPR differently). */ + processing_template_decl = 0; } /* The type denoted by decltype(e) is defined as follows: */ diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C new file mode 100644 index 0000000000000000000000000000000000000000..77357016502838b0067ba3d0d76dd15ee904aec3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C @@ -0,0 +1,6 @@ +// PR c++/104823 +// { dg-do compile { target c++11 } } + +struct S { S(int); }; +double id(double); +template<class> auto f(double v) -> decltype(S{id(v)}); // { dg-error "narrowing" } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C new file mode 100644 index 0000000000000000000000000000000000000000..c52d58f8d32930061aa961d6ef0f445d21ebfd20 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C @@ -0,0 +1,14 @@ +// Verify we correctly handle the non-dependent attribute expression which +// which we used to reject due to double folding. +// { dg-do compile { target { c++11 } } } + +struct A { + constexpr int f() const { return __alignof__(int); }; +}; + +template<class...> +void f() { + int a __attribute__((aligned(A{}.f()))); +} + +template void f();