[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-19 Thread via cfe-commits

zwuis wrote:

> Can you check this case with your build?

Also pass this test.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-19 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

> PS: Sorry for misunderstanding the original issue.

Totally understandable. Thanks for following up on this.

> These changes pass all tests above:

Can you check this case with your build?
```cpp
struct A { int x; };

char q(int *);
short q(int A::*);

template 
constexpr int f(char (*)[sizeof(q(&T::x))]) { return 1; }

template 
constexpr int f(char (*)[sizeof(q(&(T::x)))]) { return 2; }

constexpr int g(char (*p)[sizeof(char)] = 0) { return f(p); }
constexpr int h(char (*p)[sizeof(short)] = 0) { return f(p); }

static_assert(g() == 2);
static_assert(h() == 1);
```

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-19 Thread via cfe-commits

zwuis wrote:

These changes pass all tests above:

```diff
-if (isa(op) && cast(op)->getQualifier()) {
+if (isa(op) && cast(op)->getQualifier() &&
+!isa(OrigOp.get())) {
   DeclContext *Ctx = dcl->getDeclContext();
   if (Ctx && Ctx->isRecord()) {
 if (dcl->getType()->isReferenceType()) {
   Diag(OpLoc,
 diag::err_cannot_form_pointer_to_member_of_reference_type)
 << dcl->getDeclName() << dcl->getType();
   return QualType();
 }
-
-// C++11 [expr.unary.op] p4:
-// A pointer to member is only formed when an explicit & is used and
-// its operand is a qualified-id not enclosed in parentheses.
-if (isa(OrigOp.get())) {
-  SourceLocation LeftParenLoc = OrigOp.get()->getBeginLoc(),
-  RightParenLoc = OrigOp.get()->getEndLoc();
-
-  Diag(LeftParenLoc,
-diag::err_form_ptr_to_member_from_parenthesized_expr)
-  << SourceRange(OpLoc, RightParenLoc)
-  << FixItHint::CreateRemoval(LeftParenLoc)
-  << FixItHint::CreateRemoval(RightParenLoc);
-
-  // Continuing might lead to better error recovery.
-}
 
 while (cast(Ctx)->isAnonymousStructOrUnion())
   Ctx = Ctx->getParent();
 
 QualType MPTy = Context.getMemberPointerType(
 op->getType(),
 Context.getTypeDeclType(cast(Ctx)).getTypePtr());
 // Under the MS ABI, lock down the inheritance model now.
 if (Context.getTargetInfo().getCXXABI().isMicrosoft())
   (void)isCompleteType(OpLoc, MPTy);
 return MPTy;
   }
 }
```

PS: Sorry for misunderstanding the original issue.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-18 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> I can try to look at that this week. Either way be ill-formed is much better 
> than being incorrect

Thank you @cor3ntin! If it looks like you won't have a solution by Monday 
sometime, let's revert the changes so they don't end up on the release branch. 
We can cherry-pick if we think we have a rock solid solution, if needs be.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

For info, the cases where the _id-expression_ is transformed into a class 
member access expression (`q` and `h` below) do not run into this code (see 
https://cplusplus.github.io/CWG/issues/2902.html regarding said transformation):
```cpp
#include 
struct S {
  int x;

  bool q = std::is_same_v; // OK

  static void f() {
static_assert(std::is_same_v, ""); // OK
  }
  void g(this const S &) {
static_assert(std::is_same_v, ""); // OK
  }
  void h() const {
static_assert(std::is_same_v, ""); // OK
  }
};

static_assert(S{0}.q);
```

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

I think (at least part of) the fix is to add a condition to

https://github.com/llvm/llvm-project/blob/21e6777957457451196084cd48ebc42bce9619f0/clang/lib/Sema/SemaExpr.cpp#L14117-L14120

that the operand is not parenthesized. For reference, the 
address-of-member-function case checks for parentheses this way:

https://github.com/llvm/llvm-project/blob/21e6777957457451196084cd48ebc42bce9619f0/clang/lib/Sema/SemaExpr.cpp#L13908-L13912

This should address the pre-existing bug with:
```cpp
namespace std {
  template 
  struct is_same { static constexpr bool value = false; };

  template 
  struct is_same { static constexpr bool value = true; };
}
 
struct S {
int &x;
static_assert(std::is_same::value, "");
};
```

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread via cfe-commits

cor3ntin wrote:

I can try to look at that this week. Either way be ill-formed is much better 
than being incorrect

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

Thank you for spotting this, btw!

Given the proximity to the branch date, I lean towards (1) to give us time to 
figure out how to properly do (3) unless someone is starting on (3) Real Soon 
Now™. Any disagreement @cor3ntin ?

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

The optics of having something in the release notes about this (if the bug is 
not fixed properly) is not good.
Meaning that I am leaning towards options (1) or (3).

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

> Or is there a deeper issue here and I'm not seeing it?

The previous Clang behaviour produced the wrong type as the result. So the 
choices are to:

1. Do the old wrong thing: silent incorrect behaviour
2. Do the new wrong thing: produce diagnostic that may confuse users
3. Fix the type associated with the expression

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

If I'm following along correctly, both of those `static_assert`s should be 
accepted from your first example because `decltype` is an unevaluated context 
and the fix would be to change:
```
if (isa(OrigOp.get())) {
```
to instead be:
```
if (isa(OrigOp.get()) && !SemaRef.isUnevaluatedContext()) {
```
? Or is there a deeper issue here and I'm not seeing it?

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

Indeed, the new diagnostic is never valid because the permission to name 
non-static data members in unevaluated operands is not restricted by scope: 
https://eel.is/c++draft/expr.prim.id.general#4.3

https://gcc.godbolt.org/z/h4eTT984M:
```cpp
namespace std {
  template 
  struct is_same { static constexpr bool value = false; };

  template 
  struct is_same { static constexpr bool value = true; };
}
 
struct S {
int x;
static_assert(std::is_same::value, "");
static_assert(std::is_same::value, "");
};
static_assert(std::is_same::value, "");
static_assert(std::is_same::value, "");
```


https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-07-17 Thread Hubert Tong via cfe-commits

hubert-reinterpretcast wrote:

@cor3ntin @AaronBallman, the new diagnostic triggers for valid code 
(https://gcc.godbolt.org/z/fMvEaGabG):
```cpp
#include 
 
struct S {
int x;
static_assert(std::is_same::value, "");
static_assert(std::is_same::value, "");
};
```

Either the first `static_assert` is invalid or both `static_assert`s are valid.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-03 Thread via cfe-commits

github-actions[bot] wrote:



@zwuis Congratulations on having your first Pull Request (PR) merged into the 
LLVM Project!

Your changes will be combined with recent changes from other authors, then 
tested
by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with 
a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as
the builds can include changes from many authors. It is not uncommon for your
change to be included in a build that fails due to someone else's changes, or
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail 
[here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it 
yourself.
This is a normal part of [LLVM 
development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy).
 You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are 
working as expected, well done!


https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-03 Thread via cfe-commits

https://github.com/cor3ntin closed 
https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-02 Thread via cfe-commits

zwuis wrote:

> @zwuis Thanks for your contribution. Will you need me to merge that for you?

Yes. Thanks for your review!

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-02 Thread via cfe-commits

cor3ntin wrote:

@zwuis Thanks for your contribution. Will you need me to merge that for you?

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-01 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/6] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/6] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

>From 81fd55780b34c92566bdfb7fc1a2cde690675d66 Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:39:45 +0800
Subject: [PATCH 3/6] Move tests to the right place

---
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 .../CXX/expr/expr.unary/expr.unary.op/p4.cpp   | 17 +
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 3e99b333d0e584..08ab0ca56fb632 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
+// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -26,20 +27,3 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
-
-namespace GH40906 {
-  struct A {
-int val;
-void func() {}
-  };
-
-  void test() {
-decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
-int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
-
-// FIXME: Error messages in these cases are less than clear, we can do
-// better.
-int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
-void (A::* ptr3)() = &(A::func); // expec

[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-01 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/6] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/6] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

>From 81fd55780b34c92566bdfb7fc1a2cde690675d66 Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:39:45 +0800
Subject: [PATCH 3/6] Move tests to the right place

---
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 .../CXX/expr/expr.unary/expr.unary.op/p4.cpp   | 17 +
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 3e99b333d0e584..08ab0ca56fb632 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
+// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -26,20 +27,3 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
-
-namespace GH40906 {
-  struct A {
-int val;
-void func() {}
-  };
-
-  void test() {
-decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
-int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
-
-// FIXME: Error messages in these cases are less than clear, we can do
-// better.
-int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
-void (A::* ptr3)() = &(A::func); // expec

[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-01 Thread via cfe-commits


@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}

zwuis wrote:

> I think creating an issue, or a new PR is the way to go. Would that work for 
> you?

Yes. Issue made: #90822. I will create PR in a few days.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-01 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

Sorry for the delayed reply.
LGTM, thank you for your contribution!

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-05-01 Thread via cfe-commits


@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}

cor3ntin wrote:

I think creating an issue, or a new PR is the way to go. Would that work for 
you?


https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-25 Thread via cfe-commits


@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}

zwuis wrote:

> This inconsistency is irrelevant to issue 40906. I am confused about the 
> following questions:
> 
> 1. Do I need to remove these tests?
> 2. Do I need to fix this inconsistency in this PR, or a new PR?
> 3. Should I open an issue for it?

@cor3ntin Could you give me some ideas for these questions? Thank you!

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-25 Thread Brian Bi via cfe-commits

t3nsor wrote:

> @t3nsor Do you know the reason for the "not enclosed in parameters" in 
> https://eel.is/c++draft/expr.unary.op#4 ?

No I don't. If I had to guess, it might be because adding parentheses is 
intended to be used as a way to not create a pointer to member (and instead get 
an ordinary pointer to a member named by a qualified  name) sort of like how 
parentheses can be used to suppress ADL.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-25 Thread via cfe-commits

https://github.com/zwuis edited https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-25 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/5] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/5] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

>From 81fd55780b34c92566bdfb7fc1a2cde690675d66 Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:39:45 +0800
Subject: [PATCH 3/5] Move tests to the right place

---
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 .../CXX/expr/expr.unary/expr.unary.op/p4.cpp   | 17 +
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 3e99b333d0e584..08ab0ca56fb632 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
+// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -26,20 +27,3 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
-
-namespace GH40906 {
-  struct A {
-int val;
-void func() {}
-  };
-
-  void test() {
-decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
-int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
-
-// FIXME: Error messages in these cases are less than clear, we can do
-// better.
-int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
-void (A::* ptr3)() = &(A::func); // expec

[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-24 Thread via cfe-commits

cor3ntin wrote:

@t3nsor Do you know the reason for the "not enclosed in parameters" in 
https://eel.is/c++draft/expr.unary.op#4 ?

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-24 Thread via cfe-commits


@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}

zwuis wrote:

> I would expect `err_invalid_non_static_member_use` to be used there too (or 
> rather, that case should be consistent with above)

This inconsistency is irrelevant to PR 40906. I am confused about the following 
questions:

1. Do I need to remove these tests?
2. Do I need to fix this inconsistency in this PR, or a new PR?
3. Should I open an issue for it?

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-24 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/3] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/3] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

>From 81fd55780b34c92566bdfb7fc1a2cde690675d66 Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:39:45 +0800
Subject: [PATCH 3/3] Move tests to the right place

---
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 .../CXX/expr/expr.unary/expr.unary.op/p4.cpp   | 17 +
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 3e99b333d0e584..08ab0ca56fb632 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
+// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -26,20 +27,3 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
-
-namespace GH40906 {
-  struct A {
-int val;
-void func() {}
-  };
-
-  void test() {
-decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
-int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
-
-// FIXME: Error messages in these cases are less than clear, we can do
-// better.
-int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
-void (A::* ptr3)() = &(A::func); // expec

[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-24 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/3] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/3] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

>From 4481d735c5a5eb266b9ce9aad93af818a8b8d49f Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:39:45 +0800
Subject: [PATCH 3/3] Move tests to the right place

---
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp| 17 -
 .../CXX/expr/expr.unary/expr.unary.op/p4.cpp| 17 +
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 3e99b333d0e584..2dd6b23fa02496 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -26,20 +26,3 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
-
-namespace GH40906 {
-  struct A {
-int val;
-void func() {}
-  };
-
-  void test() {
-decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
-int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
-
-// FIXME: Error messages in these cases are less than clear, we can do
-// better.
-int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
-void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
-  }
-}
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp 
b/clang/test/CXX/expr/expr.unary/exp

[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-24 Thread via cfe-commits

https://github.com/zwuis updated https://github.com/llvm/llvm-project/pull/89713

>From f6fd1e5e5f42b3c72cb5aeaf9e6d4e91d5424bee Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Tue, 23 Apr 2024 14:56:12 +0800
Subject: [PATCH 1/2] Add missing check when making pointer to member

---
 clang/lib/Sema/SemaExpr.cpp| 11 +++
 .../CXX/expr/expr.unary/expr.unary.op/p3.cpp   | 18 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5c861467bc1023..824667fb722365 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();
+return QualType();
+  }
+
   while (cast(Ctx)->isAnonymousStructOrUnion())
 Ctx = Ctx->getParent();
 
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 08ab0ca56fb632..73d850a6839da7 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only %s -verify 
-// expected-no-diagnostics
 
 namespace rdar10544564 {
   // Check that we don't attempt to use an overloaded operator& when
@@ -27,3 +26,20 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr1)() = &Y::memfunc1;
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
+
+namespace test2 {
+  struct A {
+int val;
+void func() {}
+  };
+
+  void test() {
+decltype(&(A::val)) ptr1; // expected-error {{invalid use of non-static 
data member 'val'}}
+int A::* ptr2 = &(A::val); // expected-error {{invalid use of non-static 
data member 'val'}}
+
+// FIXME: Error messages in these cases are less than clear, we can do
+// better.
+int size = sizeof(&(A::func)); // expected-error {{call to non-static 
member function without an object argument}}
+void (A::* ptr3)() = &(A::func); // expected-error {{call to non-static 
member function without an object argument}}
+  }
+}

>From 22b18d32d79e5dcd0390aa17c454f373e565868a Mon Sep 17 00:00:00 2001
From: YanzuoLiu 
Date: Wed, 24 Apr 2024 17:21:14 +0800
Subject: [PATCH 2/2] Apply suggestion from cor3ntin

Co-authored-by: cor3ntin 
---
 clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp 
b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
index 73d850a6839da7..3e99b333d0e584 100644
--- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -27,7 +27,7 @@ namespace rdar10544564 {
   X (Y::*func_mem_ptr2)() = &Y::memfunc2;
 }
 
-namespace test2 {
+namespace GH40906 {
   struct A {
 int val;
 void func() {}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-23 Thread Aaron Ballman via cfe-commits


@@ -14644,6 +14644,17 @@ QualType Sema::CheckAddressOfOperand(ExprResult 
&OrigOp, SourceLocation OpLoc) {
 return QualType();
   }
 
+  // C++11 [expr.unary.op] p4:
+  // A pointer to member is only formed when an explicit & is used and
+  // its operand is a qualified-id not enclosed in parentheses.
+  if (isa(OrigOp.get())) {
+// `op->getEndLoc()` is the last part of the qualified-id.
+// For example, "baz" in "foo::bar::baz".
+Diag(op->getEndLoc(), diag::err_invalid_non_static_member_use)
+<< dcl->getDeclName() << op->getSourceRange();

AaronBallman wrote:

We should also add a fix-it to remove the parentheses as a kindness to the user.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-23 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-23 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

Thank you for the fix! You should also add a release note to 
clang/docs/ReleaseNotes.rst so that users know about the improvement.

https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] pointer to member with qualified-id enclosed in parentheses in unevaluated context should be invalid (PR #89713)

2024-04-23 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/89713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits