[Bug c++/78609] invalid member's visibility detection in constexpr with arrays

2021-07-23 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78609

Andrew Pinski  changed:

   What|Removed |Added

   Last reconfirmed||2021-07-23
Summary|invalid member's visibility |invalid member's visibility
   |detection in constexpr  |detection in constexpr with
   ||arrays
 Status|UNCONFIRMED |NEW
 Ever confirmed|0   |1

--- Comment #3 from Andrew Pinski  ---
Confirmed.  The problem is with taking the address of a field and templates.
Here is a reduced testcase:
struct A
{
private:
char data;
public:
constexpr const char *c_str() const { return  }
constexpr A(char const str) : data(str) {};
constexpr A() : data()  {};
};
template
struct B
{
static const constexpr A name = A{'a'};
static const constexpr char * value = name.c_str();
};
template
const constexpr A B::name;

const char  *c = B<0>::value;

 CUT 
If I make B a non-template, then it will work correctly.

[Bug c++/78609] invalid member's visibility detection in constexpr

2018-01-11 Thread matthijs at stdin dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78609

Matthijs Kooijman  changed:

   What|Removed |Added

 CC||matthijs at stdin dot nl

--- Comment #2 from Matthijs Kooijman  ---
I also ran into this problem. It seems that gcc somehow inlines c_str() (or
rather, evaluates the constexpr variable it is assigned to) before visibility
checks (possibly because the constexpr is evaluated before template
initialization?).

Below is a smaller example, which is confirmed broken up to gcc 8. I could not
reduce this example any further, so it seems the essential pattern that
triggers this is:
 - There is a class instance in a constexpr variable with static storage
duration
 - A pointer to a private member of this object is accessed through a method
 - This pointer is assigned to a constexpr variable
 - This pointer is assigned in a template instantiation

Here's the code:

  class foo {
  char c;
public:
  //constexpr foo(): c(1) { }
  //constexpr foo(char c): c(c) { }
  constexpr const char* c_str() const { return  }
  };

  constexpr foo basename = foo(); // Fails
  // These also fail, if you add the appropriate constructor above
  //static constexpr foo basename = foo(1); // Fails
  //static constexpr foo basename(1); // Fails
  //static constexpr foo basename{1}; // Fails
  //static constexpr foo basename{}; // Fails
  // Surprisingly this works (but needs a constructor above):
  //static constexpr foo basename; // Works

  template 
  void call() {
// This is where it breaks
constexpr const char *unused = basename.c_str();
  }

  int main() {
// Instantiate the call function
call();
  }

  // Removing the template argument on T makes it work
  // Letting T be deduced by adding an argument to call() also fails
  // Making the "unused" variable non-constexpr makes it work
  // Making get() return c instead of  makes it work
  // Making "basename" a static variable inside call() also fails
  //
  // Tested on avr-gcc avr-gcc 4.9.2, gcc Debian 6.3.0-18, gcc Debian
  // 7.2.0-19, gcc Debian 8-20180110-1


$ avr-gcc ATest.cpp -std=c++11
ATest.cpp: In instantiation of ‘void call() [with T = int]’:
ATest.cpp:26:13:   required from here
ATest.cpp:2:10: error: ‘char foo::c’ is private
 char c;
  ^
ATest.cpp:21:49: error: within this context
   constexpr const char *unused = basename.c_str();
 ^

[Bug c++/78609] invalid member's visibility detection in constexpr

2016-11-30 Thread bobk-off at yandex dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78609

--- Comment #1 from Fedor Bobkov  ---
To walk around this bug just change visibility of "data" member to public.