Bug 66477 - [constexpr] accepts-invalid with constexpr member call on non-constant reference
Summary: [constexpr] accepts-invalid with constexpr member call on non-constant reference
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.1.0
: P3 normal
Target Milestone: 10.0
Assignee: Jason Merrill
URL:
Keywords: accepts-invalid
: 92530 (view as bug list)
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2015-06-09 18:39 UTC by Richard Smith
Modified: 2021-12-02 13:28 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.3, 5.3.0, 6.0
Last reconfirmed: 2016-03-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Smith 2015-06-09 18:39:54 UTC
GCC accepts this invalid code:

  struct a { constexpr int size() const { return 3; } };
  void f(a &r) { static_assert(r.size() == 3, "error"); }

The static_assert condition is non-constant because it mentions the reference 'r' whose referent is not known within that constant expression.
Comment 1 Martin Sebor 2016-03-16 03:16:47 UTC
The invalid test case is still accepted on trunk of 6.0 and prior (interestingly, bug 60430 shows a an example of a valid program where a reference is rejected in a constexpr context).

$ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -B/home/msebor/build/gcc-trunk-svn/gcc -S -Wall -Wextra -Wpedantic -xc++ z.c && echo SUCCESS
struct a { constexpr int size() const { return 3; } };
void f(a &r) { static_assert(r.size() == 3, "error"); }
SUCCESS
Comment 2 TC 2017-03-24 19:00:16 UTC
Seems to have something to do with reference-type parameters.

  struct a { constexpr int size() const { return 3; } };
  constexpr bool g(a&) { return true;}
  void f(a &r) { 
    static_assert(r.size() == 3, "error"); // accepted
    static_assert(g(r), "");               // likewise
    a& rr = r;
    static_assert(g(rr), "");              // rejected
    static_assert(rr.size()==3, "");       // likewise
  }
Comment 3 YSC 2019-07-25 11:40:44 UTC
The invalid test case is still accepted on gcc 9.0. Popped up in a SO question (https://stackoverflow.com/q/57196229/5470596).
Comment 4 CVS Commits 2020-02-03 22:53:40 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:87fbd5347b33883006dc77e779b9edc590fcd2f0

commit r10-6417-g87fbd5347b33883006dc77e779b9edc590fcd2f0
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 3 16:03:45 2020 -0500

    c++: Fix constexpr vs. reference parameter.
    
    [expr.const] specifically rules out mentioning a reference even if its
    address is never used, because it implies indirection that is similarly
    non-constant for a pointer variable.
    
    	PR c++/66477
    	* constexpr.c (cxx_eval_constant_expression) [PARM_DECL]: Don't
    	defer loading the value of a reference.
Comment 5 Jason Merrill 2020-02-03 22:53:58 UTC
Fixed for GCC 10.
Comment 6 Jonathan Wakely 2021-12-02 13:28:39 UTC
*** Bug 92530 has been marked as a duplicate of this bug. ***