head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC4:1.1.1.4
	netbsd-11-0-RC3:1.1.1.4
	netbsd-11-0-RC2:1.1.1.4
	netbsd-11-0-RC1:1.1.1.4
	perseant-exfatfs-base-20250801:1.1.1.4
	netbsd-11:1.1.1.4.0.10
	netbsd-11-base:1.1.1.4
	netbsd-10-1-RELEASE:1.1.1.4
	perseant-exfatfs-base-20240630:1.1.1.4
	perseant-exfatfs:1.1.1.4.0.8
	perseant-exfatfs-base:1.1.1.4
	netbsd-8-3-RELEASE:1.1.1.2
	netbsd-9-4-RELEASE:1.1.1.3
	netbsd-10-0-RELEASE:1.1.1.4
	netbsd-10-0-RC6:1.1.1.4
	netbsd-10-0-RC5:1.1.1.4
	netbsd-10-0-RC4:1.1.1.4
	netbsd-10-0-RC3:1.1.1.4
	netbsd-10-0-RC2:1.1.1.4
	netbsd-10-0-RC1:1.1.1.4
	netbsd-10:1.1.1.4.0.6
	netbsd-10-base:1.1.1.4
	netbsd-9-3-RELEASE:1.1.1.3
	cjep_sun2x:1.1.1.4.0.4
	cjep_sun2x-base:1.1.1.4
	cjep_staticlib_x-base1:1.1.1.4
	netbsd-9-2-RELEASE:1.1.1.3
	cjep_staticlib_x:1.1.1.4.0.2
	cjep_staticlib_x-base:1.1.1.4
	netbsd-9-1-RELEASE:1.1.1.3
	phil-wifi-20200421:1.1.1.4
	phil-wifi-20200411:1.1.1.4
	phil-wifi-20200406:1.1.1.4
	netbsd-8-2-RELEASE:1.1.1.2
	netbsd-9-0-RELEASE:1.1.1.3
	netbsd-9-0-RC2:1.1.1.3
	netbsd-9-0-RC1:1.1.1.3
	netbsd-9:1.1.1.3.0.2
	netbsd-9-base:1.1.1.3
	phil-wifi-20190609:1.1.1.3
	netbsd-8-1-RELEASE:1.1.1.2
	netbsd-8-1-RC1:1.1.1.2
	pgoyette-compat-merge-20190127:1.1.1.2.28.1
	pgoyette-compat-20190127:1.1.1.3
	pgoyette-compat-20190118:1.1.1.3
	pgoyette-compat-1226:1.1.1.3
	pgoyette-compat-1126:1.1.1.3
	pgoyette-compat-1020:1.1.1.3
	pgoyette-compat-0930:1.1.1.3
	pgoyette-compat-0906:1.1.1.3
	netbsd-7-2-RELEASE:1.1.1.2
	pgoyette-compat-0728:1.1.1.3
	clang-337282:1.1.1.3
	netbsd-8-0-RELEASE:1.1.1.2
	phil-wifi:1.1.1.2.0.30
	phil-wifi-base:1.1.1.2
	pgoyette-compat-0625:1.1.1.2
	netbsd-8-0-RC2:1.1.1.2
	pgoyette-compat-0521:1.1.1.2
	pgoyette-compat-0502:1.1.1.2
	pgoyette-compat-0422:1.1.1.2
	netbsd-8-0-RC1:1.1.1.2
	pgoyette-compat-0415:1.1.1.2
	pgoyette-compat-0407:1.1.1.2
	pgoyette-compat-0330:1.1.1.2
	pgoyette-compat-0322:1.1.1.2
	pgoyette-compat-0315:1.1.1.2
	netbsd-7-1-2-RELEASE:1.1.1.2
	pgoyette-compat:1.1.1.2.0.28
	pgoyette-compat-base:1.1.1.2
	netbsd-7-1-1-RELEASE:1.1.1.2
	clang-319952:1.1.1.2
	matt-nb8-mediatek:1.1.1.2.0.26
	matt-nb8-mediatek-base:1.1.1.2
	clang-309604:1.1.1.2
	perseant-stdc-iso10646:1.1.1.2.0.24
	perseant-stdc-iso10646-base:1.1.1.2
	netbsd-8:1.1.1.2.0.22
	netbsd-8-base:1.1.1.2
	prg-localcount2-base3:1.1.1.2
	prg-localcount2-base2:1.1.1.2
	prg-localcount2-base1:1.1.1.2
	prg-localcount2:1.1.1.2.0.20
	prg-localcount2-base:1.1.1.2
	pgoyette-localcount-20170426:1.1.1.2
	bouyer-socketcan-base1:1.1.1.2
	pgoyette-localcount-20170320:1.1.1.2
	netbsd-7-1:1.1.1.2.0.18
	netbsd-7-1-RELEASE:1.1.1.2
	netbsd-7-1-RC2:1.1.1.2
	clang-294123:1.1.1.2
	netbsd-7-nhusb-base-20170116:1.1.1.2
	bouyer-socketcan:1.1.1.2.0.16
	bouyer-socketcan-base:1.1.1.2
	clang-291444:1.1.1.2
	pgoyette-localcount-20170107:1.1.1.2
	netbsd-7-1-RC1:1.1.1.2
	pgoyette-localcount-20161104:1.1.1.2
	netbsd-7-0-2-RELEASE:1.1.1.2
	localcount-20160914:1.1.1.2
	netbsd-7-nhusb:1.1.1.2.0.14
	netbsd-7-nhusb-base:1.1.1.2
	clang-280599:1.1.1.2
	pgoyette-localcount-20160806:1.1.1.2
	pgoyette-localcount-20160726:1.1.1.2
	pgoyette-localcount:1.1.1.2.0.12
	pgoyette-localcount-base:1.1.1.2
	netbsd-7-0-1-RELEASE:1.1.1.2
	clang-261930:1.1.1.2
	netbsd-7-0:1.1.1.2.0.10
	netbsd-7-0-RELEASE:1.1.1.2
	netbsd-7-0-RC3:1.1.1.2
	netbsd-7-0-RC2:1.1.1.2
	netbsd-7-0-RC1:1.1.1.2
	clang-237755:1.1.1.2
	clang-232565:1.1.1.2
	clang-227398:1.1.1.2
	tls-maxphys-base:1.1.1.2
	tls-maxphys:1.1.1.2.0.8
	netbsd-7:1.1.1.2.0.6
	netbsd-7-base:1.1.1.2
	clang-215315:1.1.1.2
	clang-209886:1.1.1.2
	yamt-pagecache:1.1.1.2.0.4
	yamt-pagecache-base9:1.1.1.2
	tls-earlyentropy:1.1.1.2.0.2
	tls-earlyentropy-base:1.1.1.2
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1.1.2
	riastradh-drm2-base3:1.1.1.2
	clang-202566:1.1.1.2
	clang-201163:1.1.1.2
	clang-199312:1.1.1.2
	clang-198450:1.1.1.1
	LLVM:1.1.1;
locks; strict;
comment	@// @;


1.1
date	2014.01.05.15.40.34;	author joerg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	wh3aCSIWykURqWjx;

1.1.1.1
date	2014.01.05.15.40.34;	author joerg;	state Exp;
branches;
next	1.1.1.2;
commitid	wh3aCSIWykURqWjx;

1.1.1.2
date	2014.01.15.21.26.05;	author joerg;	state Exp;
branches
	1.1.1.2.4.1
	1.1.1.2.8.1
	1.1.1.2.28.1
	1.1.1.2.30.1;
next	1.1.1.3;
commitid	NQXlzzA0SPkc5glx;

1.1.1.3
date	2018.07.17.18.31.35;	author joerg;	state Exp;
branches;
next	1.1.1.4;
commitid	wDzL46ALjrCZgwKA;

1.1.1.4
date	2019.11.13.22.22.56;	author joerg;	state dead;
branches;
next	;
commitid	QD8YATxuNG34YJKB;

1.1.1.2.4.1
date	2014.01.15.21.26.05;	author yamt;	state dead;
branches;
next	1.1.1.2.4.2;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.2.4.2
date	2014.05.22.16.19.41;	author yamt;	state Exp;
branches;
next	;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.2.8.1
date	2014.01.15.21.26.05;	author tls;	state dead;
branches;
next	1.1.1.2.8.2;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.2.8.2
date	2014.08.19.23.49.20;	author tls;	state Exp;
branches;
next	;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.2.28.1
date	2018.07.28.04.34.12;	author pgoyette;	state Exp;
branches;
next	;
commitid	1UP1xAIUxv1ZgRLA;

1.1.1.2.30.1
date	2019.06.10.21.46.36;	author christos;	state Exp;
branches;
next	1.1.1.2.30.2;
commitid	jtc8rnCzWiEEHGqB;

1.1.1.2.30.2
date	2020.04.13.07.50.23;	author martin;	state dead;
branches;
next	;
commitid	X01YhRUPVUDaec4C;


desc
@@


1.1
log
@Initial revision
@
text
@// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion

void a() {  // expected-warning{{call itself}}
  a();
}

void b(int x) {  // expected-warning{{call itself}}
  if (x)
    b(x);
  else
    b(x+1);
}

void c(int x) {
  if (x)
    c(5);
}

void d(int x) {  // expected-warning{{call itself}}
  if (x)
    ++x;
  return d(x);
}

// Doesn't warn on mutually recursive functions
void e();
void f();

void e() { f(); }
void f() { e(); }

// Don't warn on infinite loops
void g() {
  while (true)
    g();

  g();
}

void h(int x) {
  while (x < 5) {
    h(x+1);
  }
}

void i(int x) {  // expected-warning{{call itself}}
  while (x < 5) {
    --x;
  }
  i(0);
}

int j() {  // expected-warning{{call itself}}
  return 5 + j();
}

class S {
  static void a();
  void b();
};

void S::a() {  // expected-warning{{call itself}}
  return a();
}

void S::b() {  // expected-warning{{call itself}}
  int i = 0;
  do {
    ++i;
    b();
  } while (i > 5);
}

template<class member>
struct T {
  member m;
  void a() { return a(); }  // expected-warning{{call itself}}
  static void b() { return b(); }  // expected-warning{{call itself}}
};

void test_T() {
  T<int> foo;
  foo.a();  // expected-note{{in instantiation}}
  foo.b();  // expected-note{{in instantiation}}
}

class U {
  U* u;
  void Fun() {  // expected-warning{{call itself}}
    u->Fun();
  }
};

// No warnings on templated functions
// sum<0>() is instantiated, does recursively call itself, but never runs.
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>();  // This instantiates sum<0>() even if never called.
  else
    return 0;
}

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

void DoSomethingHere();

// DoStuff<0,0>() is instantiated, but never called.
template<int First, int Last>
int DoStuff() {
  if (First + 1 == Last) {
    // This branch gets removed during <0, 0> instantiation in so CFG for this
    // function goes straight to the else branch.
    DoSomethingHere();
  } else {
    DoStuff<First, (First + Last)/2>();
    DoStuff<(First + Last)/2, Last>();
  }
  return 0;
}
int stuff = DoStuff<0, 1>();
@


1.1.1.1
log
@Import clang 3.5svn r198450.
@
text
@@


1.1.1.2
log
@Import Clang 3.5svn r199312
@
text
@a129 23

template<int x>
struct Wrapper {
  static int run() {
    // Similar to the above, Wrapper<0>::run() will discard the if statement.
    if (x == 1)
      return 0;
    return Wrapper<x/2>::run();
  }
  static int run2() {  // expected-warning{{call itself}}
    return run2();
  }
};

template <int x>
int test_wrapper() {
  if (x != 0)
    return Wrapper<x>::run() +
           Wrapper<x>::run2();  // expected-note{{instantiation}}
  return 0;
}

int wrapper_sum = test_wrapper<2>();  // expected-note{{instantiation}}
@


1.1.1.2.30.1
log
@Sync with HEAD
@
text
@d32 2
a33 1
void g() {  // expected-warning{{call itself}}
a56 13
void k() {  // expected-warning{{call itself}}
  while(true) {
    k();
  }
}

// Don't warn on infinite loops
void l() {
  while (true) {}

  l();
}

@


1.1.1.2.30.2
log
@Mostly merge changes from HEAD upto 20200411
@
text
@@


1.1.1.2.28.1
log
@Sync with HEAD
@
text
@d32 2
a33 1
void g() {  // expected-warning{{call itself}}
a56 13
void k() {  // expected-warning{{call itself}}
  while(true) {
    k();
  }
}

// Don't warn on infinite loops
void l() {
  while (true) {}

  l();
}

@


1.1.1.3
log
@Import clang r337282 from trunk
@
text
@d32 2
a33 1
void g() {  // expected-warning{{call itself}}
a56 13
void k() {  // expected-warning{{call itself}}
  while(true) {
    k();
  }
}

// Don't warn on infinite loops
void l() {
  while (true) {}

  l();
}

@


1.1.1.4
log
@Mark old LLVM instance as dead.
@
text
@@


1.1.1.2.8.1
log
@file warn-infinite-recursion.cpp was added on branch tls-maxphys on 2014-08-19 23:49:20 +0000
@
text
@d1 152
@


1.1.1.2.8.2
log
@Rebase to HEAD as of a few days ago.
@
text
@a0 152
// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion

void a() {  // expected-warning{{call itself}}
  a();
}

void b(int x) {  // expected-warning{{call itself}}
  if (x)
    b(x);
  else
    b(x+1);
}

void c(int x) {
  if (x)
    c(5);
}

void d(int x) {  // expected-warning{{call itself}}
  if (x)
    ++x;
  return d(x);
}

// Doesn't warn on mutually recursive functions
void e();
void f();

void e() { f(); }
void f() { e(); }

// Don't warn on infinite loops
void g() {
  while (true)
    g();

  g();
}

void h(int x) {
  while (x < 5) {
    h(x+1);
  }
}

void i(int x) {  // expected-warning{{call itself}}
  while (x < 5) {
    --x;
  }
  i(0);
}

int j() {  // expected-warning{{call itself}}
  return 5 + j();
}

class S {
  static void a();
  void b();
};

void S::a() {  // expected-warning{{call itself}}
  return a();
}

void S::b() {  // expected-warning{{call itself}}
  int i = 0;
  do {
    ++i;
    b();
  } while (i > 5);
}

template<class member>
struct T {
  member m;
  void a() { return a(); }  // expected-warning{{call itself}}
  static void b() { return b(); }  // expected-warning{{call itself}}
};

void test_T() {
  T<int> foo;
  foo.a();  // expected-note{{in instantiation}}
  foo.b();  // expected-note{{in instantiation}}
}

class U {
  U* u;
  void Fun() {  // expected-warning{{call itself}}
    u->Fun();
  }
};

// No warnings on templated functions
// sum<0>() is instantiated, does recursively call itself, but never runs.
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>();  // This instantiates sum<0>() even if never called.
  else
    return 0;
}

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

void DoSomethingHere();

// DoStuff<0,0>() is instantiated, but never called.
template<int First, int Last>
int DoStuff() {
  if (First + 1 == Last) {
    // This branch gets removed during <0, 0> instantiation in so CFG for this
    // function goes straight to the else branch.
    DoSomethingHere();
  } else {
    DoStuff<First, (First + Last)/2>();
    DoStuff<(First + Last)/2, Last>();
  }
  return 0;
}
int stuff = DoStuff<0, 1>();

template<int x>
struct Wrapper {
  static int run() {
    // Similar to the above, Wrapper<0>::run() will discard the if statement.
    if (x == 1)
      return 0;
    return Wrapper<x/2>::run();
  }
  static int run2() {  // expected-warning{{call itself}}
    return run2();
  }
};

template <int x>
int test_wrapper() {
  if (x != 0)
    return Wrapper<x>::run() +
           Wrapper<x>::run2();  // expected-note{{instantiation}}
  return 0;
}

int wrapper_sum = test_wrapper<2>();  // expected-note{{instantiation}}
@


1.1.1.2.4.1
log
@file warn-infinite-recursion.cpp was added on branch yamt-pagecache on 2014-05-22 16:19:41 +0000
@
text
@d1 152
@


1.1.1.2.4.2
log
@sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs.  ("Protocol error: too many arguments")
@
text
@a0 152
// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion

void a() {  // expected-warning{{call itself}}
  a();
}

void b(int x) {  // expected-warning{{call itself}}
  if (x)
    b(x);
  else
    b(x+1);
}

void c(int x) {
  if (x)
    c(5);
}

void d(int x) {  // expected-warning{{call itself}}
  if (x)
    ++x;
  return d(x);
}

// Doesn't warn on mutually recursive functions
void e();
void f();

void e() { f(); }
void f() { e(); }

// Don't warn on infinite loops
void g() {
  while (true)
    g();

  g();
}

void h(int x) {
  while (x < 5) {
    h(x+1);
  }
}

void i(int x) {  // expected-warning{{call itself}}
  while (x < 5) {
    --x;
  }
  i(0);
}

int j() {  // expected-warning{{call itself}}
  return 5 + j();
}

class S {
  static void a();
  void b();
};

void S::a() {  // expected-warning{{call itself}}
  return a();
}

void S::b() {  // expected-warning{{call itself}}
  int i = 0;
  do {
    ++i;
    b();
  } while (i > 5);
}

template<class member>
struct T {
  member m;
  void a() { return a(); }  // expected-warning{{call itself}}
  static void b() { return b(); }  // expected-warning{{call itself}}
};

void test_T() {
  T<int> foo;
  foo.a();  // expected-note{{in instantiation}}
  foo.b();  // expected-note{{in instantiation}}
}

class U {
  U* u;
  void Fun() {  // expected-warning{{call itself}}
    u->Fun();
  }
};

// No warnings on templated functions
// sum<0>() is instantiated, does recursively call itself, but never runs.
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>();  // This instantiates sum<0>() even if never called.
  else
    return 0;
}

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

void DoSomethingHere();

// DoStuff<0,0>() is instantiated, but never called.
template<int First, int Last>
int DoStuff() {
  if (First + 1 == Last) {
    // This branch gets removed during <0, 0> instantiation in so CFG for this
    // function goes straight to the else branch.
    DoSomethingHere();
  } else {
    DoStuff<First, (First + Last)/2>();
    DoStuff<(First + Last)/2, Last>();
  }
  return 0;
}
int stuff = DoStuff<0, 1>();

template<int x>
struct Wrapper {
  static int run() {
    // Similar to the above, Wrapper<0>::run() will discard the if statement.
    if (x == 1)
      return 0;
    return Wrapper<x/2>::run();
  }
  static int run2() {  // expected-warning{{call itself}}
    return run2();
  }
};

template <int x>
int test_wrapper() {
  if (x != 0)
    return Wrapper<x>::run() +
           Wrapper<x>::run2();  // expected-note{{instantiation}}
  return 0;
}

int wrapper_sum = test_wrapper<2>();  // expected-note{{instantiation}}
@


