[PATCH] Add new warning to Clang to detect when all code paths in a function has a call back to the function.

Richard Trieu rtrieu at google.com
Wed Oct 9 15:57:18 PDT 2013


On Wed, Oct 9, 2013 at 2:53 PM, Arthur O'Dwyer <arthur.j.odwyer at gmail.com>wrote:

> Well, I do think that you should run this diagnostic over a few real
> codebases

Already done.  My comments with the patch reflect the results of running
this warning over Google code.


> (libc++? :)) and see whether it produces any false
> positives, first.

False positives only found in template instantiations.


> I suspect there won't be any cases in which the
> diagnostic is produced on code that an impartial observer wouldn't
> consider inelegant.


> Remember, the goal is to catch bugs involving accidental infinite
> recursion (due to human confusion with name lookup, overloading,
> template instantiation, or parameter pack expansion). If we silence
> the diagnostics on templates, then we really limit the usefulness of
> this diagnostic.
>
We also want to limit the number of false positives.  If too many false
positives trigger this, users will just disable the warning.

>
> Can you give some examples of real-world code

 (A) where this diagnostic found bugs in non-template code,
namespace bar { void foo(); }
void foo() { return foo(); }  // should be bar::foo();

class A {
  bool operator==(const A& other);
  bool operator!=(const A& other) { return *this != other; } // should be
!(*this == other)
};

struct Value { int num; };
struct Wrapper {
  int num() { return num(); }  // should be V.num;
  Value V;
};


 (B) where this diagnostic gave false positives on non-template code,
Nope, didn't find any.

 (C) where this diagnostic gave false positives on template code, and
// Same example as before.
template <int value>
int sum() {
  return value + sum<value/2>;
}

template<>
int sum<1>() { return 1; }

template<int x, int y>
int calculate_value() {
  if (x != y)
    return sum<x - y>();
  else
    return 0;
}

int value = calculate_value<1,1>();

template<int First, int Last>
void DoStuff() {
  if (First + 1 == Last) {
    DoSomethingHere();  // This gets removed during <0, 0> instantiation in
the CFG, I think.
  } else {
    DoStuff<First, (First + Last)/2>();
    DoStuff<(First + Last)/2, Last>()
  }
}
DoStuff<0, 1>()

 (D) where this diagnostic found bugs in template code?
struct Value { int num; };
template<typename T>
struct Wrapper {
  int num() { return num(); }  // should be V.num;
  T V;
};
Wrapper<Value> Foo;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131009/1a3891c2/attachment.html>


More information about the cfe-commits mailing list