Well, it depends on the FE's language definition :) For C and C++ the
above is not a constant-expression as the language defines it. I can
see a couple of obvious ways to deal with this with an FE specific
constant expression evaluator,
1) during parsing set a flag if the expression contains something
not permitted for a constant-expresssion
2) a lazy folder returns 'error' when it meets something not allowed
(and if ?: is allowed, it must go down each of its branches to determine
if they have something banned).
Front ends should be responsible for doing any constant folding that their language definition requires. Otherwise, you'd get the strange situation that legality of a program depends on the strength of the optimizers, compilation flags used or even target properties.
Your proposal to have the tree folders check wether the program obeys C/C++ languages semantics seems fundamentally flowed.
GCC's middle- and back end should not be required to do anything for
a function that it has determined will never be called. Wether an
expression is constant for the middle end may depend on many factors,
including wether a certain function call could be expanded inline or not.
Constant folding as required by language standards has a very precise definition, and does not depend on compilation options or optimization parameters. When the FE hands of a tree to the middle end, it asserts that the program conforms to the static semantics of the programming language.
This gives the optimizers the freedom to do any transformations, as long as it conforms to the language-independent definition of GIMPLE.
-Geert