sammccall marked an inline comment as done. sammccall added inline comments.
================ Comment at: clang/include/clang/AST/Expr.h:6042 /// /// For now, RecoveryExpr is type-, value- and instantiation-dependent to take /// advantage of existing machinery to deal with dependent code in C++, e.g. ---------------- Comment is stale. ================ Comment at: clang/include/clang/AST/Expr.h:6042 /// /// For now, RecoveryExpr is type-, value- and instantiation-dependent to take /// advantage of existing machinery to deal with dependent code in C++, e.g. ---------------- sammccall wrote: > Comment is stale. We should mention something about optional type preservation. ================ Comment at: clang/lib/AST/ComputeDependence.cpp:491 + auto D = + toExprDependence(E->getType()->getDependence()) | ExprDependence::Error; for (auto *S : E->subExpressions()) ---------------- Dropping type-dependence seems like the point here and is risky, doesn't dropping value- and instantiation-dependence introduce unneccesary extra risk? Probably correct and maybe useful, but splitting it into a separate change and maybe delaying it might make it easier to get the principal change to stick. ================ Comment at: clang/lib/AST/Expr.cpp:4656 #ifndef NDEBUG + assert(!T.isNull()); for (auto *E : SubExprs) ---------------- Why is this in ifndef? Actually, why is the loop in ifndef? surely the compiler can inline and remove an empty loop over an arrayref? ================ Comment at: clang/lib/Sema/SemaDecl.cpp:16427 QualType EltTy = Context.getBaseElementType(T); - if (!EltTy->isDependentType()) { + if (!EltTy->isDependentType() && !EltTy->containsErrors()) { if (RequireCompleteSizedType(Loc, EltTy, ---------------- why is this needed/does it help? I would have thought in the cases where we now don't consider the type dependent, the *type* wouldn't contain errors (rather the expression owning the type would). Is this just for decltype? ================ Comment at: clang/lib/Sema/SemaOverload.cpp:12904 - // Overload resolution failed. - return ExprError(); + // Overload resolution failed, try to recovery. + SmallVector<Expr *, 8> SubExprs = {Fn}; ---------------- nit: try to recover (or just "Overload resolution failed", what the code is doing is obvious enough here) ================ Comment at: clang/test/CodeCompletion/member-access.cpp:276 +struct S { int member; }; +S overloaded(int); ---------------- I think there's an interesting test of the "viable" case where you have a const/non-const overload set with different return types: ``` class Collection { const char *find(int) const; char* find(int) const; }; void test1(const Collection &C, Collection &NC) { C.find(); // missing arg, type const char* NC.find(); // missing arg, is type NC or is it unresolved? } ``` (Not sure if it's best written as a codecompletion test, I guess AST dump is better) ================ Comment at: clang/test/Index/getcursor-recovery.cpp:6 +void testTypedRecoveryExpr1() { + // Inner bar() is a RecoveryExpr, outer foo() is an overloaded call. + foo(x, bar(x)); ---------------- nit: unresolved overloaded call? ================ Comment at: clang/test/Index/getcursor-recovery.cpp:19 +void testTypedRecoveryExpr2() { + // Inner foo() is a RecoveryExpr (with int type), outer foo() is a "foo(int, int)" call. + foo(x, foo(x)); ---------------- nit: a valid foo(int, int) call? (just to draw the contrast) ================ Comment at: clang/test/SemaCXX/enable_if.cpp:417 -constexpr int B = 10 + // the carat for the error should be pointing to the problematic call (on the next line), not here. - callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-3{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-10{{candidate disabled}} +constexpr int B = 10 + // expected-error {{initialized by a constant expression}} + callTemplated<0>(); // expected-error@-3{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-10{{candidate disabled}} expected-note {{in call to 'callTemplated()'}} expected-note@-3 {{subexpression not valid in a constant expression}} ---------------- hokein wrote: > this diagnostic is changed slightly (without `-frecovery-ast-type`). I think > this is acceptable. > > before this patch: > > ``` > /tmp/t5.cpp:7:10: error: no matching function for call to 'templated' > return templated<N>(); // expected-error {{no matching function for call > to 'templated'}} > ^~~~~~~~~~~~ > /tmp/t5.cpp:13:5: note: in instantiation of function template specialization > 'enable_if_diags::callTemplated<0>' requested here > callTemplated<0>(); // expected-note {{in call to 'callTemplated()'}} > expected-note@-6 {{subexpression not valid in a constant expression}} > ^ > /tmp/t5.cpp:2:32: note: candidate disabled: <no message provided> > template <int N> constexpr int templated() __attribute__((enable_if(N, ""))) { > ^ ~ > /tmp/t5.cpp:13:5: error: constexpr variable 'B' must be initialized by a > constant expression > callTemplated<0>(); // expected-note {{in call to 'callTemplated()'}} > expected-note@-6 {{subexpression not valid in a constant expression}} > ^~~~~~~~~~~~~~~~~~ > 2 errors generated. > ``` > > vs after this patch: > > ``` > /tmp/t5.cpp:7:10: error: no matching function for call to 'templated' > return templated<N>(); // expected-error {{no matching function for call > to 'templated'}} > ^~~~~~~~~~~~ > /tmp/t5.cpp:13:5: note: in instantiation of function template specialization > 'enable_if_diags::callTemplated<0>' requested here > callTemplated<0>(); // expected-note {{in call to 'callTemplated()'}} > expected-note@-6 {{subexpression not valid in a constant expression}} > ^ > /tmp/t5.cpp:2:32: note: candidate disabled: <no message provided> > template <int N> constexpr int templated() __attribute__((enable_if(N, ""))) { > ^ ~ > /tmp/t5.cpp:12:15: error: constexpr variable 'B' must be initialized by a > constant expression > constexpr int B = 10 + // expected-error {{constexpr variable 'B' must be > initialized by a constant expression}} > ^ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /tmp/t5.cpp:7:10: note: subexpression not valid in a constant expression > return templated<N>(); // expected-error {{no matching function for call > to 'templated'}} > ^ > /tmp/t5.cpp:13:5: note: in call to 'callTemplated()' > callTemplated<0>(); // expected-note {{in call to 'callTemplated()'}} > expected-note@-6 {{subexpression not valid in a constant expression}} > ^ > 2 errors generated. > ``` > > Yeah, this is noisier but seems OK. Can you take a look at the blame for the split-line test and see if there was any special code to support it that can be cleaned up? ================ Comment at: clang/test/SemaCXX/recovery-expr-type.cpp:12 + // no crash. + int s = sizeof(make_indestructible()); // expected-error {{deleted}} +} ---------------- what if we make this constexpr and try to static-assert on it, use it as the size of an array etc? ================ Comment at: clang/test/SemaTemplate/instantiate-function-params.cpp:1 // RUN: %clang_cc1 -triple i686-unknown-unknown -fsyntax-only -verify %s ---------------- hokein wrote: > this test is very tricky, and hard for human to understand. It was added to > test clang not crashing. > > Different compilers (gcc, msvc) emit different diagnostics, with this patch, > clang emits 3 more errs `no type named 'type'...`, it seems reasonable, and > gcc also emits them. Ugh, I remember this test. It's partially reduced from boost IIRC. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79160/new/ https://reviews.llvm.org/D79160 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits