On Thu, Oct 26, 2017 at 6:17 AM, Paolo Carlini <paolo.carl...@oracle.com> wrote: > Hi again, > > On 24/10/2017 20:58, Jason Merrill wrote: >> >> This seems like an odd place to add the complete_type call. What >> happens if we change the COMPLETE_TYPE_P (type) in >> cp_apply_type_quals_to_decl to COMPLETE_TYPE_P (complete_type (type))? > > Finally I'm back with some information. > > Simply doing the above doesn't fully work. The first symptom is the failure > of g++.dg/init/mutable1.C which is precisely the testcase that you added > together with the "|| !COMPLETE_TYPE_P (type)" itself: clearly, the > additional condition isn't able anymore to do its work, because, first, when > the type isn't complete, TYPE_HAS_MUTABLE_P (type) is false and then, when > in fact it would be found true, we check !COMPLETE_TYPE_P (complete_type > (type)) which is false, because completing succeeded.
> Thus it seems we need at least something like: > > TREE_TYPE (decl) = type = complete_type (type); > > if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type)) > type_quals &= ~TYPE_QUAL_CONST; > > But then, toward the end of the testsuite, we notice a more serious issue, > which is unrelated to the above: g++.old-deja/g++.pt/poi1.C > > // { dg-do assemble } > // Origin: Gerald Pfeifer <pfei...@dbai.tuwien.ac.at> > > template <class T> > class TLITERAL : public T > { > int x; > }; > > class GATOM; > > typedef TLITERAL<GATOM> x; > extern TLITERAL<GATOM> y; > > also fails: > > poi1.C: In instantiation of ‘class TLITERAL<GATOM>’: > poi1.C:13:24: required from here > poi1.C:5:7: error: invalid use of incomplete type ‘class GATOM’ > class TLITERAL : public T > poi1.C:10:7: note: forward declaration of ‘class GATOM’ > class GATOM; > > that is, trying to complete GATOM at the 'extern TLITERAL<GATOM> y;" line > obviously fails. Note, in case isn't obvious, that this happens exactly for > the cp_apply_type_quals_to_decl call at the end of grokdeclarator which I > tried to change in my first try: the failure of poi1.C seems rather useful > to figure out what we want to do for this bug. > > Well, as expected, explicitly checking VAR_P && DECL_DECLARED_CONSTEXPR_P > works again - it seems to me that after all it could make sense given the > comment precisely talking about the additional complexities related to > constexpr. Anyway, I'm attaching the corresponding complete patch. Looking at the code again, it seems that the problem is the difference between start_decl_1 and grokfield, in that the former has /* If an explicit initializer is present, or if this is a definition of an aggregate, then we need a complete type at this point. (Scalars are always complete types, so there is nothing to check.) This code just sets COMPLETE_P; errors (if necessary) are issued below. */ if ((initialized || aggregate_definition_p) && !complete_p && COMPLETE_TYPE_P (complete_type (type))) { complete_p = true; /* We will not yet have set TREE_READONLY on DECL if the type was "const", but incomplete, before this point. But, now, we have a complete type, so we can try again. */ cp_apply_type_quals_to_decl (cp_type_quals (type), decl); } and grokfield/finish_static_data_member_decl don't. How about completing the type and re-applying the quals in finish_static_data_member_decl if there's an initializer? Your most recent patch ought to work, but is less parallel. Sorry for the churn. Jason