Message ID | 20200119203448.957706-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | [C++] PR c++/93324 - ICE with -Wall on constexpr if. | expand |
On Sun, Jan 19, 2020 at 03:34:48PM -0500, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > * semantics.c (is_std_constant_evaluated_p): Check fndecl. > > * g++.dg/cpp1z/constexpr-if33.C: New test. > --- > gcc/cp/semantics.c | 4 ++-- > gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C | 16 ++++++++++++++++ > 2 files changed, 18 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C > > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c > index 3669b247e34..9051a2863e0 100644 > --- a/gcc/cp/semantics.c > +++ b/gcc/cp/semantics.c > @@ -734,8 +734,8 @@ is_std_constant_evaluated_p (tree fn) > return false; > > tree fndecl = cp_get_callee_fndecl_nofold (fn); > - if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, > - BUILT_IN_FRONTEND)) > + if (fndecl && fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, > + BUILT_IN_FRONTEND)) > return true; > > if (!decl_in_std_namespace_p (fndecl)) Shouldn't it instead do if (fndecl == NULL_TREE) return false; before the fndecl_built_in_p check? While decl_in_std_namespace_p apparently will return false for NULL argument, relying on that is werid. Jakub
On Sun, Jan 19, 2020 at 10:00:42PM +0100, Jakub Jelinek wrote: > On Sun, Jan 19, 2020 at 03:34:48PM -0500, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > * semantics.c (is_std_constant_evaluated_p): Check fndecl. > > > > * g++.dg/cpp1z/constexpr-if33.C: New test. > > --- > > gcc/cp/semantics.c | 4 ++-- > > gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C | 16 ++++++++++++++++ > > 2 files changed, 18 insertions(+), 2 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C > > > > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c > > index 3669b247e34..9051a2863e0 100644 > > --- a/gcc/cp/semantics.c > > +++ b/gcc/cp/semantics.c > > @@ -734,8 +734,8 @@ is_std_constant_evaluated_p (tree fn) > > return false; > > > > tree fndecl = cp_get_callee_fndecl_nofold (fn); > > - if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, > > - BUILT_IN_FRONTEND)) > > + if (fndecl && fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, > > + BUILT_IN_FRONTEND)) > > return true; > > > > if (!decl_in_std_namespace_p (fndecl)) > > Shouldn't it instead do > if (fndecl == NULL_TREE) > return false; > before the fndecl_built_in_p check? > > While decl_in_std_namespace_p apparently will return false for NULL > argument, relying on that is werid. Can do that, too. -- >8 -- This is a crash with constexpr if, when trying to see if the call in the if-statement is std::is_constant_evaluated. cp_get_callee_fndecl_nofold can return NULL_TREE and fndecl_built_in_p doesn't expect to get a null tree, so check FNDECL first. Bootstrapped/regtested on x86_64-linux, ok for trunk? * semantics.c (is_std_constant_evaluated_p): Check fndecl. * g++.dg/cpp1z/constexpr-if33.C: New test. --- gcc/cp/semantics.c | 3 +++ gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3669b247e34..3b88f1520bc 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -734,6 +734,9 @@ is_std_constant_evaluated_p (tree fn) return false; tree fndecl = cp_get_callee_fndecl_nofold (fn); + if (fndecl == NULL_TREE) + return false; + if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, BUILT_IN_FRONTEND)) return true; diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C new file mode 100644 index 00000000000..e5ef659932b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C @@ -0,0 +1,16 @@ +// PR c++/93324 - ICE with -Wall on constexpr if. +// { dg-do compile { target c++17 } } +// { dg-options "-Wall" } + +struct { + template <int> + static constexpr bool a() { return 0; } +} e; + +template <typename> +void d() +{ + auto c(e); + using b = decltype(c); + if constexpr (b::a<2>()); +} base-commit: bcfc2227c556f2801a657ce3007374732baa8333
On 1/19/20 4:18 PM, Marek Polacek wrote: > On Sun, Jan 19, 2020 at 10:00:42PM +0100, Jakub Jelinek wrote: >> On Sun, Jan 19, 2020 at 03:34:48PM -0500, Marek Polacek wrote: >>> Bootstrapped/regtested on x86_64-linux, ok for trunk? >>> >>> * semantics.c (is_std_constant_evaluated_p): Check fndecl. >>> >>> * g++.dg/cpp1z/constexpr-if33.C: New test. >>> --- >>> gcc/cp/semantics.c | 4 ++-- >>> gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C | 16 ++++++++++++++++ >>> 2 files changed, 18 insertions(+), 2 deletions(-) >>> create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C >>> >>> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c >>> index 3669b247e34..9051a2863e0 100644 >>> --- a/gcc/cp/semantics.c >>> +++ b/gcc/cp/semantics.c >>> @@ -734,8 +734,8 @@ is_std_constant_evaluated_p (tree fn) >>> return false; >>> >>> tree fndecl = cp_get_callee_fndecl_nofold (fn); >>> - if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, >>> - BUILT_IN_FRONTEND)) >>> + if (fndecl && fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, >>> + BUILT_IN_FRONTEND)) >>> return true; >>> >>> if (!decl_in_std_namespace_p (fndecl)) >> >> Shouldn't it instead do >> if (fndecl == NULL_TREE) >> return false; >> before the fndecl_built_in_p check? >> >> While decl_in_std_namespace_p apparently will return false for NULL >> argument, relying on that is werid. > > Can do that, too. > > -- >8 -- > This is a crash with constexpr if, when trying to see if the call in > the if-statement is std::is_constant_evaluated. > > cp_get_callee_fndecl_nofold can return NULL_TREE and fndecl_built_in_p > doesn't expect to get a null tree, so check FNDECL first. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? OK. > * semantics.c (is_std_constant_evaluated_p): Check fndecl. > > * g++.dg/cpp1z/constexpr-if33.C: New test. > --- > gcc/cp/semantics.c | 3 +++ > gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C | 16 ++++++++++++++++ > 2 files changed, 19 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C > > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c > index 3669b247e34..3b88f1520bc 100644 > --- a/gcc/cp/semantics.c > +++ b/gcc/cp/semantics.c > @@ -734,6 +734,9 @@ is_std_constant_evaluated_p (tree fn) > return false; > > tree fndecl = cp_get_callee_fndecl_nofold (fn); > + if (fndecl == NULL_TREE) > + return false; > + > if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, > BUILT_IN_FRONTEND)) > return true; > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C > new file mode 100644 > index 00000000000..e5ef659932b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C > @@ -0,0 +1,16 @@ > +// PR c++/93324 - ICE with -Wall on constexpr if. > +// { dg-do compile { target c++17 } } > +// { dg-options "-Wall" } > + > +struct { > + template <int> > + static constexpr bool a() { return 0; } > +} e; > + > +template <typename> > +void d() > +{ > + auto c(e); > + using b = decltype(c); > + if constexpr (b::a<2>()); > +} > > base-commit: bcfc2227c556f2801a657ce3007374732baa8333 >
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3669b247e34..9051a2863e0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -734,8 +734,8 @@ is_std_constant_evaluated_p (tree fn) return false; tree fndecl = cp_get_callee_fndecl_nofold (fn); - if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, - BUILT_IN_FRONTEND)) + if (fndecl && fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, + BUILT_IN_FRONTEND)) return true; if (!decl_in_std_namespace_p (fndecl)) diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C new file mode 100644 index 00000000000..e5ef659932b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if33.C @@ -0,0 +1,16 @@ +// PR c++/93324 - ICE with -Wall on constexpr if. +// { dg-do compile { target c++17 } } +// { dg-options "-Wall" } + +struct { + template <int> + static constexpr bool a() { return 0; } +} e; + +template <typename> +void d() +{ + auto c(e); + using b = decltype(c); + if constexpr (b::a<2>()); +}