Mark Mitchell wrote: > I understand what you're after: tolerate uses of the extension where > it's sufficiently harmless. > > I don't think your proposed solution is correct, though, because we want > to maintain the invariant that all conforming programs compile and > behave as required by the standard in all compilation modes. In other > words, supplying -fpermissive and friends can make non-conforming > programs compile, when they otherwise wouldn't, but conforming programs > should behave identically in all modes.
I think this is consistent with my proposal -- the first example was non-conforming, but accepted without -pedantic (as we do with other zero-sized arrays). The second example was conforming and the only way to alter its behavior was with the -fpermissive option. > I would imagine that if we encounter a zero-sized array when the > "complain" flag is tf_error, then we can just issue a conditional > pedwarn, with "if (pedantic) pedwarn (...)". But, if tf_error is not > set, we must reject the instantiation. > > I know that sounds backwards. The point is that when tf_error is set, > we're committed to the instantiation. When tf_error is not set, SFINAE > applies. And, in a conforming program, we must reject the instantiation > in that case. This is interesting - that's exactly the approach I came up (well, the part about using the complain flag to determine whether to reject the instantiation), but I was concerned about whether it would be accepted, since it seemed a bit awkward. FWIW, attached is my last iteration of the patch -- it does pass all regression tests on i686-linux and arm-elf. If we can come to an agreement on the desired behavior and it matches, I'll submit it for official approval. Thanks! - Josh
Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 106267) +++ gcc/cp/pt.c (working copy) @@ -7065,25 +7065,27 @@ tsubst (tree t, tree args, tsubst_flags_ max = tsubst_template_arg (omax, args, complain, in_decl); max = fold_decl_constant_value (max); - if (integer_zerop (omax)) - { - /* Still allow an explicit array of size zero. */ - if (pedantic) - pedwarn ("creating array with size zero"); - } - else if (integer_zerop (max) - || (TREE_CODE (max) == INTEGER_CST - && INT_CST_LT (max, integer_zero_node))) - { - /* [temp.deduct] + /* [temp.deduct] - Type deduction may fail for any of the following - reasons: + Type deduction may fail for any of the following + reasons: - Attempting to create an array with a size that is - zero or negative. */ + Attempting to create an array with a size that is + zero or negative. */ + if (integer_zerop (max) && flag_pedantic_errors + && ! (complain & tf_error)) + { + /* We must fail if performing argument deduction (as + indicated by the state of complain), so that + another substitution can be found (unless -fpermissive + was given). */ + return error_mark_node; + } + else if (TREE_CODE (max) == INTEGER_CST + && INT_CST_LT (max, integer_zero_node)) + { if (complain & tf_error) - error ("creating array with size zero (%qE)", max); + error ("creating array with negative size (%qE)", max); return error_mark_node; }