r225140 - Remove an assert that's not true on invalid code.

Richard Smith richard at metafoo.co.uk
Mon Jan 5 07:11:06 PST 2015


On Sun, Jan 4, 2015 at 6:00 PM, Nico Weber <thakis at chromium.org> wrote:

> On Sun, Jan 4, 2015 at 4:30 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> Maybe we should fix this when we create the Expr rather than putting
>> parse error recovery logic in AST?
>>
> Is that how this is usually done? I thought usually AST nodes for invalid
> code end up with invalid SourceLocs.
>

Well, invalid expressions usually don't create AST nodes at all. I think
these are reasonable guiding principles:

- error recovery code should be limited in scope to the code that performs
the error recovery
- after error recovery, we should form "approximately" valid AST so that
consumers of the AST don't need to worry about whether they deal correctly
with broken AST fragments
- AST nodes (even those created by error recovery) should have valid source
locations so that later diagnostics have somewhere to point

I would expect there are places where we don't follow these principles (and
I'd expect many of those places result in bugs like the one you were fixing
here).


> On 4 Jan 2015 20:37, "Nico Weber" <nicolasweber at gmx.de> wrote:
>>
>>> Author: nico
>>> Date: Sun Jan  4 14:32:12 2015
>>> New Revision: 225140
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=225140&view=rev
>>> Log:
>>> Remove an assert that's not true on invalid code.
>>>
>>> r185773 added an assert that checked that a CXXUnresolvedConstructExpr
>>> either
>>> has a valid rparen, or exactly one argument.  This doesn't have to be
>>> true for
>>> invalid inputs.  Convert the assert to an if, and add a test for this
>>> case.
>>>
>>> Found by SLi's afl bot.
>>>
>>> Added:
>>>     cfe/trunk/test/Misc/ast-dump-invalid.cpp
>>> Modified:
>>>     cfe/trunk/include/clang/AST/ExprCXX.h
>>>     cfe/trunk/test/SemaCXX/return.cpp
>>>
>>> Modified: cfe/trunk/include/clang/AST/ExprCXX.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=225140&r1=225139&r2=225140&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
>>> +++ cfe/trunk/include/clang/AST/ExprCXX.h Sun Jan  4 14:32:12 2015
>>> @@ -2915,8 +2915,9 @@ public:
>>>
>>>    SourceLocation getLocStart() const LLVM_READONLY;
>>>    SourceLocation getLocEnd() const LLVM_READONLY {
>>> -    assert(RParenLoc.isValid() || NumArgs == 1);
>>> -    return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd();
>>> +    if (!RParenLoc.isValid() && NumArgs > 0)
>>> +      return getArg(NumArgs - 1)->getLocEnd();
>>> +    return RParenLoc;
>>>    }
>>>
>>>    static bool classof(const Stmt *T) {
>>>
>>> Added: cfe/trunk/test/Misc/ast-dump-invalid.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-invalid.cpp?rev=225140&view=auto
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/Misc/ast-dump-invalid.cpp (added)
>>> +++ cfe/trunk/test/Misc/ast-dump-invalid.cpp Sun Jan  4 14:32:12 2015
>>> @@ -0,0 +1,20 @@
>>> +// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu
>>> -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck
>>> -check-prefix CHECK -strict-whitespace %s
>>> +
>>> +namespace TestInvalidRParenOnCXXUnresolvedConstructExpr {
>>> +template <class T>
>>> +void f(T i, T j) {
>>> +  return T (i, j;
>>> +}
>>> +}
>>> +
>>> +// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}}
>>> TestInvalidRParenOnCXXUnresolvedConstructExpr
>>> +// CHECK-NEXT: `-FunctionTemplateDecl
>>> +// CHECK-NEXT:   |-TemplateTypeParmDecl
>>> +// CHECK-NEXT:   `-FunctionDecl
>>> +// CHECK-NEXT:     |-ParmVarDecl
>>> +// CHECK-NEXT:     |-ParmVarDecl
>>> +// CHECK-NEXT:     `-CompoundStmt
>>> +// CHECK-NEXT:       `-ReturnStmt
>>> +// CHECK-NEXT:         `-CXXUnresolvedConstructExpr {{.*}} <col:10,
>>> col:16> 'T'
>>> +// CHECK-NEXT:           |-DeclRefExpr {{.*}} <col:13> 'T' lvalue
>>> ParmVar {{.*}} 'i' 'T'
>>> +// CHECK-NEXT:           `-DeclRefExpr {{.*}} <col:16> 'T' lvalue
>>> ParmVar {{.*}} 'j' 'T'
>>>
>>> Modified: cfe/trunk/test/SemaCXX/return.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return.cpp?rev=225140&r1=225139&r2=225140&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/SemaCXX/return.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/return.cpp Sun Jan  4 14:32:12 2015
>>> @@ -112,3 +112,11 @@ namespace ctor_returns_void {
>>>      ~S() { return f(); } // expected-error {{destructor '~S' must not
>>> return void expression}}
>>>    };
>>>  }
>>> +
>>> +void cxx_unresolved_expr() {
>>> +  // The use of an undeclared variable tricks clang into building a
>>> +  // CXXUnresolvedConstructExpr, and the missing ')' gives it an
>>> invalid source
>>> +  // location for its rparen.  Check that emitting a diag on the range
>>> of the
>>> +  // expr doesn't assert.
>>> +  return int(undeclared, 4; // expected-error {{expected ')'}}
>>> expected-note{{to match this '('}} expected-error {{void function
>>> 'cxx_unresolved_expr' should not return a value}} expected-error {{use of
>>> undeclared identifier 'undeclared'}}
>>> +}
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150105/878f8ee7/attachment.html>


More information about the cfe-commits mailing list