On Fri, 9 Nov 2018 at 11:32, Kyrill Tkachov <kyrylo.tkac...@foss.arm.com> wrote: > > > On 09/11/18 10:28, Matthew Malcomson wrote: > > (Third attempt to put this on the mailing list now -- today is not a good > > day for my email skills :-[) > > > > Hi there, > > > > This patch has caused a few g++ and libstdc++ regression test failures on > > arm, > > > > I've included the g++ failures below. > > > > Do you mind looking into this? > > Cheers, > > > > Matthew > > > > > > dg-cmp-results.sh: Verbosity is 2, Variant is "" > > > > Older log file: just-before-problemcase-g++.sum > > Test Run By matthew on Thu Nov 8 16:45:40 2018 > > Target is arm-none-eabi > > Host is x86_64-pc-linux-gnu > > > > Newer log file: g++-after-problem.sum > > Test Run By matthew on Thu Nov 8 21:36:14 2018 > > Target is arm-none-eabi > > Host is x86_64-pc-linux-gnu > > > > PASS->FAIL: g++.dg/cpp0x/constexpr-static12.C -std=c++14 > > scan-assembler-not _ZNSt10unique_ptrC1Ei > > PASS->FAIL: g++.dg/cpp0x/constexpr-static12.C -std=c++17 > > scan-assembler-not _ZNSt10unique_ptrC1Ei > > PASS->FAIL: g++.dg/cpp0x/constexpr-static3.C -std=gnu++14 > > scan-assembler-not static_initialization > > PASS->FAIL: g++.dg/cpp0x/constexpr-static3.C -std=gnu++17 > > scan-assembler-not static_initialization > > PASS->FAIL: g++.dg/cpp0x/constexpr-static.C -std=gnu++14 > > scan-assembler-not static_initialization > > PASS->FAIL: g++.dg/cpp0x/constexpr-static.C -std=gnu++17 > > scan-assembler-not static_initialization > > PASS->FAIL: g++.dg/cpp0x/implicit13.C -std=c++14 scan-assembler-not > > _ZN1BC1Ev > > PASS->FAIL: g++.dg/cpp0x/implicit13.C -std=c++17 scan-assembler-not > > _ZN1BC1Ev > > NA->FAIL: g++.dg/cpp0x/pr83734.C -std=gnu++14 (internal compiler error) > > PASS->FAIL: g++.dg/cpp0x/pr83734.C -std=gnu++14 (test for excess errors) > > NA->FAIL: g++.dg/cpp0x/pr83734.C -std=gnu++17 (internal compiler error) > > PASS->FAIL: g++.dg/cpp0x/pr83734.C -std=gnu++17 (test for excess errors) > > PASS->FAIL: g++.dg/cpp1y/constexpr-empty3.C -std=c++14 scan-assembler-not > > static_init > > PASS->FAIL: g++.dg/cpp1y/constexpr-empty3.C -std=c++17 scan-assembler-not > > static_init > > > > > > I believe these are tracked in > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87935 FWIW. >
Yes, that was my intention. > Kyrill > > > On 05/11/18 02:06, Jason Merrill wrote: > > The initialized_type hunk fixes handling of void AGGR_INIT_EXPRs that call a > > non-constructor; an AGGR_INIT_EXPR can have void type if its initialization > > semantics are more complicated than just expanding the call. > > > > The cxx_eval_vec_init_1 hunk corrects AGGR_INIT_EXPRs that were > > nonsensically built to initialize an object of void type. And the > > build_aggr_init_expr hunk makes sure we don't do that again. > > > > The ocp_convert and cxx_eval_outermost_constant_expr hunks deal with making > > sure that a constant CONSTRUCTOR has the right type. > > > > Tested x86_64-pc-linux-gnu, applying to trunk. > > > > * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR. > > * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling. > > (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR. > > (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the > > right type. Don't wrap a CONSTRUCTOR if one was passed in. > > * tree.c (build_aggr_init_expr): Check for void. > > --- > > gcc/cp/constexpr.c | 22 +++++++++++++--------- > > gcc/cp/cvt.c | 10 +++++++++- > > gcc/cp/tree.c | 2 ++ > > gcc/cp/ChangeLog | 7 +++++++ > > 4 files changed, 31 insertions(+), 10 deletions(-) > > > > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > > index 7692b1727da..4fb1ba527e3 100644 > > --- a/gcc/cp/constexpr.c > > +++ b/gcc/cp/constexpr.c > > @@ -2778,8 +2778,10 @@ initialized_type (tree t) > > { > > if (TYPE_P (t)) > > return t; > > - tree type = cv_unqualified (TREE_TYPE (t)); > > - if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR) > > + tree type = TREE_TYPE (t); > > + if (!VOID_TYPE_P (type)) > > + /* No need to look deeper. */; > > + else if (TREE_CODE (t) == CALL_EXPR) > > { > > /* A constructor call has void type, so we need to look deeper. */ > > tree fn = get_function_named_in_call (t); > > @@ -2787,7 +2789,9 @@ initialized_type (tree t) > > && DECL_CXX_CONSTRUCTOR_P (fn)) > > type = DECL_CONTEXT (fn); > > } > > - return type; > > + else if (TREE_CODE (t) == AGGR_INIT_EXPR) > > + type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t)); > > + return cv_unqualified (type); > > } > > /* We're about to initialize element INDEX of an array or class from > > VALUE. > > @@ -3000,7 +3004,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree > > atype, tree init, > > &argvec, elttype, LOOKUP_NORMAL, > > complain); > > release_tree_vector (argvec); > > - init = build_aggr_init_expr (TREE_TYPE (init), init); > > + init = build_aggr_init_expr (elttype, init); > > pre_init = true; > > } > > @@ -5089,7 +5093,7 @@ cxx_eval_outermost_constant_expr (tree t, bool > > allow_non_constant, > > r = build_nop (TREE_TYPE (r), r); > > TREE_CONSTANT (r) = false; > > } > > - else if (non_constant_p || r == t) > > + else if (non_constant_p) > > return t; > > if (should_unshare) > > @@ -5097,18 +5101,18 @@ cxx_eval_outermost_constant_expr (tree t, bool > > allow_non_constant, > > if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r))) > > { > > + r = adjust_temp_type (type, r); > > if (TREE_CODE (t) == TARGET_EXPR > > && TARGET_EXPR_INITIAL (t) == r) > > return t; > > - else > > + else if (TREE_CODE (t) != CONSTRUCTOR) > > { > > r = get_target_expr (r); > > TREE_CONSTANT (r) = true; > > - return r; > > } > > } > > - else > > - return r; > > + > > + return r; > > } > > /* Returns true if T is a valid subexpression of a constant expression, > > diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c > > index 315b0d6a65a..b04e9a70652 100644 > > --- a/gcc/cp/cvt.c > > +++ b/gcc/cp/cvt.c > > @@ -725,7 +725,8 @@ ocp_convert (tree type, tree expr, int convtype, int > > flags, > > /* We need a new temporary; don't take this shortcut. */; > > else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE > > (e))) > > { > > - if (same_type_p (type, TREE_TYPE (e))) > > + tree etype = TREE_TYPE (e); > > + if (same_type_p (type, etype)) > > /* The call to fold will not always remove the NOP_EXPR as > > might be expected, since if one of the types is a typedef; > > the comparison in fold is just equality of pointers, not a > > @@ -743,9 +744,16 @@ ocp_convert (tree type, tree expr, int convtype, int > > flags, > > { > > /* Don't build a NOP_EXPR of class type. Instead, change the > > type of the temporary. */ > > + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype)); > > TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type; > > return e; > > } > > + else if (TREE_CODE (e) == CONSTRUCTOR) > > + { > > + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype)); > > + TREE_TYPE (e) = type; > > + return e; > > + } > > else > > { > > /* We shouldn't be treating objects of ADDRESSABLE type as > > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c > > index 74018e97bb7..51af9f2015e 100644 > > --- a/gcc/cp/tree.c > > +++ b/gcc/cp/tree.c > > @@ -576,6 +576,8 @@ build_aggr_init_expr (tree type, tree init) > > tree rval; > > int is_ctor; > > + gcc_assert (!VOID_TYPE_P (type)); > > + > > /* Don't build AGGR_INIT_EXPR in a template. */ > > if (processing_template_decl) > > return init; > > diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog > > index 7e9c0e2642a..4f40627a226 100644 > > --- a/gcc/cp/ChangeLog > > +++ b/gcc/cp/ChangeLog > > @@ -1,5 +1,12 @@ > > 2018-11-04 Jason Merrill <ja...@redhat.com><mailto:ja...@redhat.com> > > + * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR. > > + * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling. > > + (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR. > > + (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the > > + right type. Don't wrap a CONSTRUCTOR if one was passed in. > > + * tree.c (build_aggr_init_expr): Check for void. > > + > > PR c++/60503 - wrong lambda attribute syntax. > > * parser.c (cp_parser_lambda_declarator_opt): Fix attribute > > handling. > > > > base-commit: 703d2f69fad4772dc4aedb5327b5e3d88e8e1843 > > > > > > On 05/11/18 02:06, Jason Merrill wrote: > > > > The initialized_type hunk fixes handling of void AGGR_INIT_EXPRs that call a > > non-constructor; an AGGR_INIT_EXPR can have void type if its initialization > > semantics are more complicated than just expanding the call. > > > > The cxx_eval_vec_init_1 hunk corrects AGGR_INIT_EXPRs that were > > nonsensically built to initialize an object of void type. And the > > build_aggr_init_expr hunk makes sure we don't do that again. > > > > The ocp_convert and cxx_eval_outermost_constant_expr hunks deal with making > > sure that a constant CONSTRUCTOR has the right type. > > > > Tested x86_64-pc-linux-gnu, applying to trunk. > > > > * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR. > > * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling. > > (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR. > > (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the > > right type. Don't wrap a CONSTRUCTOR if one was passed in. > > * tree.c (build_aggr_init_expr): Check for void. > > --- > > gcc/cp/constexpr.c | 22 +++++++++++++--------- > > gcc/cp/cvt.c | 10 +++++++++- > > gcc/cp/tree.c | 2 ++ > > gcc/cp/ChangeLog | 7 +++++++ > > 4 files changed, 31 insertions(+), 10 deletions(-) > > > > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > > index 7692b1727da..4fb1ba527e3 100644 > > --- a/gcc/cp/constexpr.c > > +++ b/gcc/cp/constexpr.c > > @@ -2778,8 +2778,10 @@ initialized_type (tree t) > > { > > if (TYPE_P (t)) > > return t; > > - tree type = cv_unqualified (TREE_TYPE (t)); > > - if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR) > > + tree type = TREE_TYPE (t); > > + if (!VOID_TYPE_P (type)) > > + /* No need to look deeper. */; > > + else if (TREE_CODE (t) == CALL_EXPR) > > { > > /* A constructor call has void type, so we need to look deeper. */ > > tree fn = get_function_named_in_call (t); > > @@ -2787,7 +2789,9 @@ initialized_type (tree t) > > && DECL_CXX_CONSTRUCTOR_P (fn)) > > type = DECL_CONTEXT (fn); > > } > > - return type; > > + else if (TREE_CODE (t) == AGGR_INIT_EXPR) > > + type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t)); > > + return cv_unqualified (type); > > } > > > > /* We're about to initialize element INDEX of an array or class from VALUE. > > @@ -3000,7 +3004,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree > > atype, tree init, > > &argvec, elttype, LOOKUP_NORMAL, > > complain); > > release_tree_vector (argvec); > > - init = build_aggr_init_expr (TREE_TYPE (init), init); > > + init = build_aggr_init_expr (elttype, init); > > pre_init = true; > > } > > > > @@ -5089,7 +5093,7 @@ cxx_eval_outermost_constant_expr (tree t, bool > > allow_non_constant, > > r = build_nop (TREE_TYPE (r), r); > > TREE_CONSTANT (r) = false; > > } > > - else if (non_constant_p || r == t) > > + else if (non_constant_p) > > return t; > > > > if (should_unshare) > > @@ -5097,18 +5101,18 @@ cxx_eval_outermost_constant_expr (tree t, bool > > allow_non_constant, > > > > if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r))) > > { > > + r = adjust_temp_type (type, r); > > if (TREE_CODE (t) == TARGET_EXPR > > && TARGET_EXPR_INITIAL (t) == r) > > return t; > > - else > > + else if (TREE_CODE (t) != CONSTRUCTOR) > > { > > r = get_target_expr (r); > > TREE_CONSTANT (r) = true; > > - return r; > > } > > } > > - else > > - return r; > > + > > + return r; > > } > > > > /* Returns true if T is a valid subexpression of a constant expression, > > diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c > > index 315b0d6a65a..b04e9a70652 100644 > > --- a/gcc/cp/cvt.c > > +++ b/gcc/cp/cvt.c > > @@ -725,7 +725,8 @@ ocp_convert (tree type, tree expr, int convtype, int > > flags, > > /* We need a new temporary; don't take this shortcut. */; > > else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e))) > > { > > - if (same_type_p (type, TREE_TYPE (e))) > > + tree etype = TREE_TYPE (e); > > + if (same_type_p (type, etype)) > > /* The call to fold will not always remove the NOP_EXPR as > > might be expected, since if one of the types is a typedef; > > the comparison in fold is just equality of pointers, not a > > @@ -743,9 +744,16 @@ ocp_convert (tree type, tree expr, int convtype, int > > flags, > > { > > /* Don't build a NOP_EXPR of class type. Instead, change the > > type of the temporary. */ > > + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, > > etype)); > > TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type; > > return e; > > } > > + else if (TREE_CODE (e) == CONSTRUCTOR) > > + { > > + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, > > etype)); > > + TREE_TYPE (e) = type; > > + return e; > > + } > > else > > { > > /* We shouldn't be treating objects of ADDRESSABLE type as > > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c > > index 74018e97bb7..51af9f2015e 100644 > > --- a/gcc/cp/tree.c > > +++ b/gcc/cp/tree.c > > @@ -576,6 +576,8 @@ build_aggr_init_expr (tree type, tree init) > > tree rval; > > int is_ctor; > > > > + gcc_assert (!VOID_TYPE_P (type)); > > + > > /* Don't build AGGR_INIT_EXPR in a template. */ > > if (processing_template_decl) > > return init; > > diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog > > index 7e9c0e2642a..4f40627a226 100644 > > --- a/gcc/cp/ChangeLog > > +++ b/gcc/cp/ChangeLog > > @@ -1,5 +1,12 @@ > > 2018-11-04 Jason Merrill <ja...@redhat.com><mailto:ja...@redhat.com> > > > > + * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR. > > + * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling. > > + (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR. > > + (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the > > + right type. Don't wrap a CONSTRUCTOR if one was passed in. > > + * tree.c (build_aggr_init_expr): Check for void. > > + > > PR c++/60503 - wrong lambda attribute syntax. > > * parser.c (cp_parser_lambda_declarator_opt): Fix attribute > > handling. > > > > base-commit: 703d2f69fad4772dc4aedb5327b5e3d88e8e1843 > > >