diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2013-07-25 15:04:03 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2013-07-25 15:04:03 +0000 |
commit | 4004afb38a53d7cc555dbd7bd2c1b05c1791d531 (patch) | |
tree | 22aacde1eed0277223702196c6f7d2af42ab40e9 | |
parent | 105164bb90473c48540764fb9676c0e81a1adf9b (diff) | |
download | gcc-4004afb38a53d7cc555dbd7bd2c1b05c1791d531.zip gcc-4004afb38a53d7cc555dbd7bd2c1b05c1791d531.tar.gz gcc-4004afb38a53d7cc555dbd7bd2c1b05c1791d531.tar.bz2 |
re PR c++/57981 (ICE in this code)
/cp
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57981
* decl.c (check_default_argument): Take a tsubst_flags_t parameter.
(grokparms): Adjust.
* parser.c (cp_parser_late_parse_one_default_arg): Likewise.
* pt.c (tsubst_default_argument, tsubst_default_arguments): Take
a tsubst_flags_t parameter.
(tsubst_decl): Adjust.
* call.c (convert_default_arg): Likewise.
* cp-tree.h (check_default_argument, tsubst_default_argument):
Update declarations.
/testsuite
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57981
* g++.dg/cpp0x/pr57981.C: New.
/cp
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57880
* parser.c (cp_parser_operator, case CPP_WSTRING, CPP_STRING16,
CPP_STRING32, CPP_UTF8STRING, CPP_WSTRING_USERDEF,
CPP_STRING16_USERDEF, CPP_STRING32_USERDEF, CPP_UTF8STRING_USERDEF):
Fix string_len management, tidy.
/testsuite
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57880
* g++.dg/cpp1y/udlit-empty-string-neg.C: New.
From-SVN: r201245
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/parser.c | 30 | ||||
-rw-r--r-- | gcc/cp/pt.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr57981.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C | 21 |
9 files changed, 112 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d725040..2669375 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2013-07-25 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57981 + * decl.c (check_default_argument): Take a tsubst_flags_t parameter. + (grokparms): Adjust. + * parser.c (cp_parser_late_parse_one_default_arg): Likewise. + * pt.c (tsubst_default_argument, tsubst_default_arguments): Take + a tsubst_flags_t parameter. + (tsubst_decl): Adjust. + * call.c (convert_default_arg): Likewise. + * cp-tree.h (check_default_argument, tsubst_default_argument): + Update declarations. + +2013-07-25 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57880 + * parser.c (cp_parser_operator, case CPP_WSTRING, CPP_STRING16, + CPP_STRING32, CPP_UTF8STRING, CPP_WSTRING_USERDEF, + CPP_STRING16_USERDEF, CPP_STRING32_USERDEF, CPP_UTF8STRING_USERDEF): + Fix string_len management, tidy. + 2013-07-24 Paolo Carlini <paolo.carlini@oracle.com> PR c++/57942 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3bb90ef..e8d5260 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6439,7 +6439,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum, push_defarg_context (fn); if (fn && DECL_TEMPLATE_INFO (fn)) - arg = tsubst_default_argument (fn, type, arg); + arg = tsubst_default_argument (fn, type, arg, complain); /* Due to: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4a2271f..200e78a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5222,7 +5222,7 @@ extern tree static_fn_type (tree); extern void revert_static_member_fn (tree); extern void fixup_anonymous_aggr (tree); extern tree compute_array_index_type (tree, tree, tsubst_flags_t); -extern tree check_default_argument (tree, tree); +extern tree check_default_argument (tree, tree, tsubst_flags_t); typedef int (*walk_namespaces_fn) (tree, void *); extern int walk_namespaces (walk_namespaces_fn, void *); @@ -5504,7 +5504,8 @@ extern tree maybe_process_partial_specialization (tree); extern tree most_specialized_instantiation (tree); extern void print_candidates (tree); extern void instantiate_pending_templates (int); -extern tree tsubst_default_argument (tree, tree, tree); +extern tree tsubst_default_argument (tree, tree, tree, + tsubst_flags_t); extern tree tsubst (tree, tree, tsubst_flags_t, tree); extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool, bool); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6fe4fed..7d6fe0d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10883,7 +10883,7 @@ local_variable_p_walkfn (tree *tp, int *walk_subtrees, DECL, if there is no DECL available. */ tree -check_default_argument (tree decl, tree arg) +check_default_argument (tree decl, tree arg, tsubst_flags_t complain) { tree var; tree decl_type; @@ -10915,13 +10915,14 @@ check_default_argument (tree decl, tree arg) A default argument expression is implicitly converted to the parameter type. */ ++cp_unevaluated_operand; - perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error, + perform_implicit_conversion_flags (decl_type, arg, complain, LOOKUP_IMPLICIT); --cp_unevaluated_operand; if (warn_zero_as_null_pointer_constant && TYPE_PTR_OR_PTRMEM_P (decl_type) && null_ptr_cst_p (arg) + && (complain & tf_warning) && maybe_warn_zero_as_null_pointer_constant (arg, input_location)) return nullptr_node; @@ -10935,10 +10936,14 @@ check_default_argument (tree decl, tree arg) var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL); if (var) { - if (DECL_NAME (var) == this_identifier) - permerror (input_location, "default argument %qE uses %qD", arg, var); - else - error ("default argument %qE uses local variable %qD", arg, var); + if (complain & tf_warning_or_error) + { + if (DECL_NAME (var) == this_identifier) + permerror (input_location, "default argument %qE uses %qD", + arg, var); + else + error ("default argument %qE uses local variable %qD", arg, var); + } return error_mark_node; } @@ -11089,7 +11094,7 @@ grokparms (tree parmlist, tree *parms) if (any_error) init = NULL_TREE; else if (init && !processing_template_decl) - init = check_default_argument (decl, init); + init = check_default_argument (decl, init, tf_warning_or_error); } DECL_CHAIN (decl) = decls; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3a526c2..56a017f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12261,7 +12261,6 @@ cp_parser_operator (cp_parser* parser) tree id = NULL_TREE; cp_token *token; bool bad_encoding_prefix = false; - int string_len = 2; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -12462,19 +12461,21 @@ cp_parser_operator (cp_parser* parser) return ansi_opname (ARRAY_REF); case CPP_WSTRING: - string_len = 3; case CPP_STRING16: case CPP_STRING32: - string_len = 5; case CPP_UTF8STRING: - string_len = 4; - bad_encoding_prefix = true; + bad_encoding_prefix = true; + /* Fall through. */ + case CPP_STRING: if (cxx_dialect == cxx98) maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS); if (bad_encoding_prefix) - error ("invalid encoding prefix in literal operator"); - if (TREE_STRING_LENGTH (token->u.value) > string_len) + { + error ("invalid encoding prefix in literal operator"); + return error_mark_node; + } + if (TREE_STRING_LENGTH (token->u.value) > 2) { error ("expected empty string after %<operator%> keyword"); return error_mark_node; @@ -12505,21 +12506,23 @@ cp_parser_operator (cp_parser* parser) } case CPP_WSTRING_USERDEF: - string_len = 3; case CPP_STRING16_USERDEF: case CPP_STRING32_USERDEF: - string_len = 5; case CPP_UTF8STRING_USERDEF: - string_len = 4; bad_encoding_prefix = true; + /* Fall through. */ + case CPP_STRING_USERDEF: if (cxx_dialect == cxx98) maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS); if (bad_encoding_prefix) - error ("invalid encoding prefix in literal operator"); + { + error ("invalid encoding prefix in literal operator"); + return error_mark_node; + } { tree string_tree = USERDEF_LITERAL_VALUE (token->u.value); - if (TREE_STRING_LENGTH (string_tree) > string_len) + if (TREE_STRING_LENGTH (string_tree) > 2) { error ("expected empty string after %<operator%> keyword"); return error_mark_node; @@ -22996,7 +22999,8 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl, /* In a non-template class, check conversions now. In a template, we'll wait and instantiate these as needed. */ if (TREE_CODE (decl) == PARM_DECL) - parsed_arg = check_default_argument (parmtype, parsed_arg); + parsed_arg = check_default_argument (parmtype, parsed_arg, + tf_warning_or_error); else { int flags = LOOKUP_IMPLICIT; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 38eba29..82c72dd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -184,7 +184,7 @@ static int coerce_template_template_parms (tree, tree, tsubst_flags_t, tree, tree); static bool template_template_parm_bindings_ok_p (tree, tree); static int template_args_equal (tree, tree); -static void tsubst_default_arguments (tree); +static void tsubst_default_arguments (tree, tsubst_flags_t); static tree for_each_template_parm_r (tree *, int *, void *); static tree copy_default_args_to_explicit_spec_1 (tree, tree); static void copy_default_args_to_explicit_spec (tree); @@ -9875,7 +9875,7 @@ tsubst_aggr_type (tree t, FN), which has the indicated TYPE. */ tree -tsubst_default_argument (tree fn, tree type, tree arg) +tsubst_default_argument (tree fn, tree type, tree arg, tsubst_flags_t complain) { tree saved_class_ptr = NULL_TREE; tree saved_class_ref = NULL_TREE; @@ -9915,7 +9915,7 @@ tsubst_default_argument (tree fn, tree type, tree arg) stack. */ ++function_depth; arg = tsubst_expr (arg, DECL_TI_ARGS (fn), - tf_warning_or_error, NULL_TREE, + complain, NULL_TREE, /*integral_constant_expression_p=*/false); --function_depth; pop_deferring_access_checks(); @@ -9927,12 +9927,13 @@ tsubst_default_argument (tree fn, tree type, tree arg) cp_function_chain->x_current_class_ref = saved_class_ref; } - if (errorcount+sorrycount > errs) + if (errorcount+sorrycount > errs + && (complain & tf_warning_or_error)) inform (input_location, " when instantiating default argument for call to %D", fn); /* Make sure the default argument is reasonable. */ - arg = check_default_argument (type, arg); + arg = check_default_argument (type, arg, complain); pop_access_scope (fn); @@ -9942,7 +9943,7 @@ tsubst_default_argument (tree fn, tree type, tree arg) /* Substitute into all the default arguments for FN. */ static void -tsubst_default_arguments (tree fn) +tsubst_default_arguments (tree fn, tsubst_flags_t complain) { tree arg; tree tmpl_args; @@ -9963,7 +9964,8 @@ tsubst_default_arguments (tree fn) if (TREE_PURPOSE (arg)) TREE_PURPOSE (arg) = tsubst_default_argument (fn, TREE_VALUE (arg), - TREE_PURPOSE (arg)); + TREE_PURPOSE (arg), + complain); } /* Substitute the ARGS into the T, which is a _DECL. Return the @@ -10323,7 +10325,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (!member && !PRIMARY_TEMPLATE_P (gen_tmpl) && !uses_template_parms (argvec)) - tsubst_default_arguments (r); + tsubst_default_arguments (r, complain); } else DECL_TEMPLATE_INFO (r) = NULL_TREE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3812c7e..b47813e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2013-07-25 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57981 + * g++.dg/cpp0x/pr57981.C: New. + +2013-07-25 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/57880 + * g++.dg/cpp1y/udlit-empty-string-neg.C: New. + 2013-07-25 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/57960 diff --git a/gcc/testsuite/g++.dg/cpp0x/pr57981.C b/gcc/testsuite/g++.dg/cpp0x/pr57981.C new file mode 100644 index 0000000..5ee1f0e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr57981.C @@ -0,0 +1,17 @@ +// { dg-options "-std=c++11 -Wall -Wextra" } + +template<class T> +void f(T t, void* = 0) // { dg-warning "unused parameter" } +{ +} + +template<class T> +auto g(T t) -> decltype(f(t)) +{ + f(t); +} + +int main() +{ + g(0); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C b/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C new file mode 100644 index 0000000..d0eed91 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C @@ -0,0 +1,21 @@ +// { dg-options -std=c++1y } + +int +operator "*"_s(unsigned long long) // { dg-error "expected empty string after 'operator'" } +{ return 0; } + +int +operator L"*"_Ls(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator u"*"_s16(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator U"*"_s32(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator u8"*"_u8s(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } |