[cfe-dev] -Wunreachable-code and templates

David Blaikie dblaikie at gmail.com
Wed Nov 30 22:09:52 PST 2011


> My concern, however, is that this approach is still fundamentally flawed.
>  By analyzing the instantiations, we are still impacted by the control-flow
> of that particular instantiation.  For example, suppose we have:
> template <typename T> void foo() {
>   {
>     T x;
>   }
>   printf("is this dead?");
> }
> If the instantiated type for 'T' has a 'noreturn' destructor, then the
> printf() call is unreachable.  If it doesn't, it is reachable.
>
> A simpler example:
> template <typename T> void foo() {
>   T::bar();
>   printf("is this dead?");
> }
> Same issue as before.  'bar()' could be marked 'noreturn', but it depends on
> the instantiation.  Thus control-flow could vary significantly between
> instantiations.

So the next issue I've encountered in LLVM's code is:

  if (sizeof(long) == sizeof(int))

Do we need to suppress any constant evaluation of conditions that
involve sizeof/alignof/offsetof/etc expressions? (perhaps this could
be implemented using the technique you mentioned earlier - flagging
certain edges as hidden for certain reasons so that the reachable code
analysis could examine them without interfering with other analyses -
at least at first glance it doesn't seem like these suffer from the
same complexities as templates). So far as I can see this would
involve plumbing through the logic in ExprConstant.cpp with an extra
output parameter specifying whether the evaluation of the expression
included any of these special expressions, yes?

While chatting about this on IRC - Chandler brought up the other case
you had briefly touched on: macros. These seem to suffer from all the
same issues as templates, but perhaps even worse - a single macro in
any function could exhibit the same problems as the template case:

[[noreturn]] void foo();
void bar();
#ifdef X
#define CALL foo();
#else
#define CALL bar();
#endif

int main() {
  CALL
  baz(); // unreachable?
}

Does this mean we can't analyze any function involving macros? That
would seem overly limiting. Should we try to record more detail about
the graph again, such as where a branch (or lack of one) came from?
How practical is that?

- David




More information about the cfe-dev mailing list