This is an archive of the discontinued LLVM Phabricator instance.

Perform access checking to private members in simple requirement.
ClosedPublic

Authored by usaxena95 on Dec 22 2022, 4:45 AM.

Details

Summary

Dependent access checks.

Fixes: https://github.com/llvm/llvm-project/issues/53364

We previously ignored dependent access checks to private members.
These are visible only to the RequiresExprBodyExpr (through PerformDependentDiagnositcs) and not to the individual requirements.


Non-dependent access checks.

Fixes: https://github.com/llvm/llvm-project/issues/53334
Access to members in a non-dependent context would always yield an
invalid expression. When it appears in a requires-expression, then this
is a hard error as this would always result in a substitution failure.

https://eel.is/c++draft/expr.prim.req#general-note-1

Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]
If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.

The main issue here is the delaying of the diagnostics.
Use a ParsingDeclRAIIObject creates a separate diagnostic pool for diagnositcs associated to the RequiresExprBodyDecl.
This is important because dependent diagnostics should not be leaked/delayed to higher scopes (Eg. inside a template function or in a trailing requires). These dependent diagnostics must be attached to the DeclContext of the parameters of RequiresExpr (which is the RequiresExprBodyDecl in this case).
Non dependent diagnostics, on the other hand, should not delayed and surfaced as hard errors.

Diff Detail

Event Timeline

usaxena95 created this revision.Dec 22 2022, 4:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 22 2022, 4:45 AM
usaxena95 requested review of this revision.Dec 22 2022, 4:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 22 2022, 4:45 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
shafik added a subscriber: shafik.Dec 22 2022, 7:56 AM

Thank you for the fix, can you elaborate on the motivation for this change, it looks like setting setNamingClass allows for improved diagnostics but I would like it explained better in the PR description.

clang/lib/Sema/SemaTemplateInstantiate.cpp
2243

Why this change?

usaxena95 updated this revision to Diff 485725.Dec 30 2022, 1:07 PM

Perform access-dependent checks after transforming requires clause.
This is more generic and less invasive than the previous version which changed RebuildMemberExpr and also produced duplicate diagnostics.

usaxena95 edited the summary of this revision. (Show Details)Dec 30 2022, 1:18 PM
usaxena95 updated this revision to Diff 485726.Dec 30 2022, 1:19 PM

Improved comment and added comment.

ilya-biryukov added inline comments.Jan 3 2023, 8:00 AM
clang/lib/Sema/SemaTemplateInstantiate.cpp
1365

Other uses of PerformDependentDiagnostics happen inside LocalInstantiationScope and after substitution of inner parts.

I suggest following this pattern and moving the added code after the call to inherited::TransformRequiresExpr.
I do not have any concrete examples where the current approach fails, but it's better to have a single mode of operation across all opeartions.

1366

Other uses of PerformDependentDiagnostics do not add an explicit SFINAETrap AFAICS.
Why is RequiresExpr special? Because it should "eat" the errors and only return a value?

clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
157

Could you add a check that in the following case we mention access check in the note to the no matching function to call error?

template <class T> struct Use;

class X { int a; friend struct Use<short>; };

template <class T> struct Use {
  static void foo() requires (requires (X x) { x.a; }) {
  }
};

void test() {
    Use<int>::foo();
}
usaxena95 updated this revision to Diff 486255.Jan 4 2023, 6:09 AM
usaxena95 marked 3 inline comments as done.

Adding access check related changes from https://reviews.llvm.org/D140876

usaxena95 added a reviewer: Restricted Project.Jan 4 2023, 6:09 AM
usaxena95 edited the summary of this revision. (Show Details)Jan 4 2023, 6:29 AM
usaxena95 marked an inline comment as done.Jan 4 2023, 7:24 AM
usaxena95 added inline comments.
clang/lib/Sema/SemaTemplateInstantiate.cpp
1366

Yes. Precisely.

clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
157

Added. This does not produce any diagnostics. Investigating!

usaxena95 updated this revision to Diff 486313.Jan 4 2023, 8:59 AM
usaxena95 marked an inline comment as done.

Added more tests. Still investigating libcxx failure and tests.

usaxena95 updated this revision to Diff 486357.Jan 4 2023, 11:53 AM

Return a valid RequriesExpr instead of a ExprError in case of depenedent diagnositcs.
We would also need to store the diagnositcs in the RequiresExpr for better diagnosis.

usaxena95 updated this revision to Diff 486604.Jan 5 2023, 9:27 AM

Use ParsingDeclRAIIObject instead of ContextRAII.

This creates a separate diagnostic pool for diagnositcs associated to the RequiresExprBodyDecl.
This is important because dependent diagnostics should not leak to higher scopes (Eg. inside a template function or in a trailing requires). These dependent diagnstics must be attached to the DeclContext of the parameters of RequiresExpr (which is the BodyDecl in this case).
Non dependent diagnostics should not delayed and surfaced as hard errors.

This addresses the previously failing LibCXX failure as well.

usaxena95 edited the summary of this revision. (Show Details)Jan 5 2023, 9:33 AM

I think the only major problem is not checking for error case when accessing TransReq, the rest are NITs.
Thanks for the change! Will be happy to LGTM it as soon as the access to TransReq is fixed.

clang/lib/Parse/ParseExprCXX.cpp
3512

NIT: could you add a comment explaining that we need this helper in order to capture dependent diagnostics properly?

clang/lib/Sema/SemaConcept.cpp
1005

NIT: s/Store/RequiresExpr should store dependent diagnostics. I was confused at first and thought we need to store something in this function rather than the other place.
NIT2: Use of FIXME is more common in LLVM.
NIT3: Google LDAP usx might be trickier to find in LLVM communication channels, I suggest removing it completely or using a full name instead.

clang/lib/Sema/SemaTemplateInstantiate.cpp
1372

NIT: LLVM uses FIXME more often.

1374

TransReq may be ExprError and this will cause a crash. Worth adding a test too.

1374

Could you please add assert(!TransReq || *TransReq != E).
The common optimization in TreeTransform is to avoid rebuilding the AST nodes if nothing changes. There is no optimization like this for RequireExpr right now, but it would not be unexpected if this gets implemented in the future.

In those situations, the current code can potentially change value of isSatisfied for an existing expression rather than for a newly created, which seems like asking for trouble. It would be nice to give an early warning to implementors of this optimization that they should think how to handle this case.

clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
235

NIT: FIXME

usaxena95 marked 6 inline comments as done.

Addressed comments.

clang/lib/Sema/SemaTemplateInstantiate.cpp
1374

Thanks for spotting. Adding a test with invalid requirement which caused a crash.

Remove new lines.

ilya-biryukov accepted this revision.Jan 11 2023, 2:00 AM

LGTM, thanks for fixing this!

This revision is now accepted and ready to land.Jan 11 2023, 2:00 AM
This revision was landed with ongoing or failed builds.Jan 11 2023, 3:14 AM
This revision was automatically updated to reflect the committed changes.
RKSimon added inline comments.
clang/docs/ReleaseNotes.rst
739

@usaxena95 This has broken the sphinx buildbot - please can you take a look? https://lab.llvm.org/buildbot/#/builders/92/builds/38512

erichkeane added inline comments.
clang/docs/ReleaseNotes.rst
739

Looks like he already fixed it in 75c0d43e857dd

RKSimon added inline comments.Jan 11 2023, 6:49 AM
clang/docs/ReleaseNotes.rst
739

Thanks!

Hi,

When I run the new testcase
clang/test/SemaCXX/invalid-requirement-requires-expr.cpp
with ASAN binaries the test fails like

FAIL: Clang :: SemaCXX/invalid-requirement-requires-expr.cpp (1 of 1)
******************** TEST 'Clang :: SemaCXX/invalid-requirement-requires-expr.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';   /repo/uabelho/main-github/llvm/build-all-bbisdk-asan/bin/clang -cc1 -internal-isystem /repo/uabelho/main-github/llvm/build-all-bbisdk-asan/lib/clang/16/include -nostdsysteminc /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp -I/repo/uabelho/main-github/clang/test/SemaCXX -std=c++2a -verify
--
Exit Code: 1

Command Output (stderr):
--
error: 'warning' diagnostics seen but not expected: 
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely
error: 'note' diagnostics seen but not expected: 
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while checking the satisfaction of nested requirement requested here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: in instantiation of member function 'A<9660>::far' requested here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while substituting template arguments into constraint expression here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while checking the satisfaction of nested requirement requested here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: in instantiation of requirement here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: (skipping 1697 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while substituting template arguments into constraint expression here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while checking the satisfaction of nested requirement requested here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: in instantiation of requirement here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 18: while checking the satisfaction of nested requirement requested here
  File /repo/uabelho/main-github/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp Line 23: in instantiation of member function 'A<10001>::far' requested here
12 errors generated.

--

********************
********************
Failed Tests (1):
  Clang :: SemaCXX/invalid-requirement-requires-expr.cpp


Testing Time: 0.16s
  Failed: 1

Anyone else see this?

Anyone else see this?

I have not checked, but I would not be surprised if we hit the stack size limits with asan enabled
@usaxena95, maybe reduce the number of instantiations from 10001 to 1001 or 101? It should not change the intention of the test and fix this failure.

Anyone else see this?

I have not checked, but I would not be surprised if we hit the stack size limits with asan enabled
@usaxena95, maybe reduce the number of instantiations from 10001 to 1001 or 101? It should not change the intention of the test and fix this failure.

This is a regression that was noticed by @aaron.ballman even without ASAN, so this is something that needs doing ASAP. The branch is happening around the 24th, so this needs to be fixed by then.

clang/lib/Sema/SemaTemplateInstantiate.cpp
1366

'auto' isn't allowed here by coding standard, this needs to be ExprResult.

usaxena95 marked 4 inline comments as done.Jan 13 2023, 11:47 AM

I have deleted the test in https://github.com/llvm/llvm-project/commit/a3b632ab8772237ae23638f702bdceda028b2016.
It is safe to delete as this is a brittle test trying to generate an invalid requirement using very deep template instantiation. I would find a better way to test this in another forward patch.