r213120 - Improve error recovery around colon.

Serge Pavlov sepavloff at gmail.com
Wed Jul 16 11:49:05 PDT 2014


Hi Evgeniy,

There is nothing in r213120, that could cause memory leaks
in NestedNameSpecifierLocBuilder, maybe this change triggered existing
problem.
Sanitizer reports leaks of tiny blocks (1 byte), in r213178 such blocks
should not be created. However I am not sure if this can help.

By the way, how I can build compiler with sanitizer enabled? When I create
build using command:

cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DLLVM_ENABLE_ASSERTIONS=ON \
    -DCMAKE_C_COMPILER=$CLANGPATH/clang \
    -DCMAKE_CXX_COMPILER=$CLANGPATH/clang++ \
    -DLLVM_USE_SANITIZER=Memory \
    -DLLVM_TARGETS_TO_BUILD=X86 \
    ../llvm

make fails:

[  6%] Building Intrinsics.gen...
==25305== WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x7fb534d9dedd in _M_dispose
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/bits/basic_string.h:240:34
...


Thanks,
--Serge


2014-07-16 19:50 GMT+07:00 Evgeniy Stepanov <eugeni.stepanov at gmail.com>:

> Hi,
>
> is looks like there are new memory leaks from this change:
>
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/3963/steps/check-clang%20asan/logs/stdio
>
> On Wed, Jul 16, 2014 at 9:16 AM, Serge Pavlov <sepavloff at gmail.com> wrote:
> > Author: sepavloff
> > Date: Wed Jul 16 00:16:52 2014
> > New Revision: 213120
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=213120&view=rev
> > Log:
> > Improve error recovery around colon.
> >
> > Recognize additional cases, when '::' is mistyped as ':'.
> > This is a fix to RP18587 - colons have too much protection in
> member-declarations
> > Review is tracked by http://reviews.llvm.org/D3653.
> >
> > This is an attempt to recommit the fix, initially committed as r212957
> but then
> > reverted in r212965 as it broke self-build. In the updated patch
> ParseDirectDeclarator
> > turns on colon protection in for context as well.
> >
> > Modified:
> >     cfe/trunk/lib/Parse/ParseDecl.cpp
> >     cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> >     cfe/trunk/test/SemaCXX/enum-bitfield.cpp
> >     cfe/trunk/test/SemaCXX/for-range-examples.cpp
> >     cfe/trunk/test/SemaCXX/nested-name-spec.cpp
> >
> > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=213120&r1=213119&r2=213120&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Jul 16 00:16:52 2014
> > @@ -2715,24 +2715,23 @@ void Parser::ParseDeclarationSpecifiers(
> >        // typedef-name
> >      case tok::kw_decltype:
> >      case tok::identifier: {
> > +      // This identifier can only be a typedef name if we haven't
> already seen
> > +      // a type-specifier.  Without this check we misparse:
> > +      //  typedef int X; struct Y { short X; };  as 'short int'.
> > +      if (DS.hasTypeSpecifier())
> > +        goto DoneWithDeclSpec;
> > +
> >        // In C++, check to see if this is a scope specifier like
> foo::bar::, if
> >        // so handle it as such.  This is important for ctor parsing.
> >        if (getLangOpts().CPlusPlus) {
> >          if (TryAnnotateCXXScopeToken(EnteringContext)) {
> > -          if (!DS.hasTypeSpecifier())
> > -            DS.SetTypeSpecError();
> > +          DS.SetTypeSpecError();
> >            goto DoneWithDeclSpec;
> >          }
> >          if (!Tok.is(tok::identifier))
> >            continue;
> >        }
> >
> > -      // This identifier can only be a typedef name if we haven't
> already seen
> > -      // a type-specifier.  Without this check we misparse:
> > -      //  typedef int X; struct Y { short X; };  as 'short int'.
> > -      if (DS.hasTypeSpecifier())
> > -        goto DoneWithDeclSpec;
> > -
> >        // Check for need to substitute AltiVec keyword tokens.
> >        if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
> >          break;
> > @@ -4529,7 +4528,9 @@ void Parser::ParseDeclaratorInternal(Dec
> >    // Member pointers get special handling, since there's no place for
> the
> >    // scope spec in the generic path below.
> >    if (getLangOpts().CPlusPlus &&
> > -      (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
> > +      (Tok.is(tok::coloncolon) ||
> > +       (Tok.is(tok::identifier) &&
> > +        (NextToken().is(tok::coloncolon) || NextToken().is(tok::less)))
> ||
> >         Tok.is(tok::annot_cxxscope))) {
> >      bool EnteringContext = D.getContext() == Declarator::FileContext ||
> >                             D.getContext() == Declarator::MemberContext;
> > @@ -4722,6 +4723,14 @@ void Parser::ParseDirectDeclarator(Decla
> >    DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
> >
> >    if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
> > +    // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a
> class, in
> > +    // this context it is a bitfield. Also in range-based for statement
> colon
> > +    // may delimit for-range-declaration.
> > +    ColonProtectionRAIIObject X(*this,
> > +                                D.getContext() ==
> Declarator::MemberContext ||
> > +                                    (D.getContext() ==
> Declarator::ForContext &&
> > +                                     getLangOpts().CPlusPlus11));
> > +
> >      // ParseDeclaratorInternal might already have parsed the scope.
> >      if (D.getCXXScopeSpec().isEmpty()) {
> >        bool EnteringContext = D.getContext() == Declarator::FileContext
> ||
> >
> > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=213120&r1=213119&r2=213120&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Jul 16 00:16:52 2014
> > @@ -1239,7 +1239,8 @@ void Parser::ParseClassSpecifier(tok::To
> >    // Parse the (optional) nested-name-specifier.
> >    CXXScopeSpec &SS = DS.getTypeSpecScope();
> >    if (getLangOpts().CPlusPlus) {
> > -    // "FOO : BAR" is not a potential typo for "FOO::BAR".
> > +    // "FOO : BAR" is not a potential typo for "FOO::BAR".  In this
> context it
> > +    // is a base-specifier-list.
> >      ColonProtectionRAIIObject X(*this);
> >
> >      if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
> EnteringContext))
> > @@ -1926,14 +1927,8 @@ void Parser::ParseCXXMemberDeclaratorBef
> >    //   declarator pure-specifier[opt]
> >    //   declarator brace-or-equal-initializer[opt]
> >    //   identifier[opt] ':' constant-expression
> > -  if (Tok.isNot(tok::colon)) {
> > -    // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this
> context it
> > -    // is a bitfield.
> > -    // FIXME: This should only apply when parsing the id-expression (see
> > -    // PR18587).
> > -    ColonProtectionRAIIObject X(*this);
> > +  if (Tok.isNot(tok::colon))
> >      ParseDeclarator(DeclaratorInfo);
> > -  }
> >
> >    if (!DeclaratorInfo.isFunctionDeclarator() &&
> TryConsumeToken(tok::colon)) {
> >      BitfieldSize = ParseConstantExpression();
> > @@ -2015,6 +2010,14 @@ void Parser::ParseCXXClassMemberDeclarat
> >      return;
> >    }
> >
> > +  // Turn on colon protection early, while parsing declspec, although
> there is
> > +  // nothing to protect there. It prevents from false errors if error
> recovery
> > +  // incorrectly determines where the declspec ends, as in the example:
> > +  //   struct A { enum class B { C }; };
> > +  //   const int C = 4;
> > +  //   struct D { A::B : C; };
> > +  ColonProtectionRAIIObject X(*this);
> > +
> >    // Access declarations.
> >    bool MalformedTypeSpec = false;
> >    if (!TemplateInfo.Kind &&
> > @@ -2128,13 +2131,11 @@ void Parser::ParseCXXClassMemberDeclarat
> >    if (MalformedTypeSpec)
> >      DS.SetTypeSpecError();
> >
> > -  {
> > -    // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this
> context it
> > -    // is a bitfield.
> > -    ColonProtectionRAIIObject X(*this);
> > -    ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
> > -                               &CommonLateParsedAttrs);
> > -  }
> > +  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
> > +                             &CommonLateParsedAttrs);
> > +
> > +  // Turn off colon protection that was set for declspec.
> > +  X.restore();
> >
> >    // If we had a free-standing type definition with a missing
> semicolon, we
> >    // may get this far before the problem becomes obvious.
> >
> > Modified: cfe/trunk/test/SemaCXX/enum-bitfield.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enum-bitfield.cpp?rev=213120&r1=213119&r2=213120&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/enum-bitfield.cpp (original)
> > +++ cfe/trunk/test/SemaCXX/enum-bitfield.cpp Wed Jul 16 00:16:52 2014
> > @@ -16,3 +16,15 @@ struct Y {
> >    enum E : int(2);
> >    enum E : Z(); // expected-error{{integral constant expression must
> have integral or unscoped enumeration type, not 'Z'}}
> >  };
> > +
> > +namespace pr18587 {
> > +struct A {
> > +  enum class B {
> > +    C
> > +  };
> > +};
> > +const int C = 4;
> > +struct D {
> > +  A::B : C;
> > +};
> > +}
> >
> > Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=213120&r1=213119&r2=213120&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)
> > +++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Wed Jul 16 00:16:52
> 2014
> > @@ -227,3 +227,15 @@ namespace test7 {
> >      for (e [[deprecated]] : arr) { e = 0; } // expected-warning
> {{deprecated}} expected-note {{here}} expected-warning {{extension}}
> >    }
> >  }
> > +
> > +namespace pr18587 {
> > +  class Arg {};
> > +  struct Cont {
> > +    int *begin();
> > +    int *end();
> > +  };
> > +  void AddAllArgs(Cont &x) {
> > +    for (auto Arg: x) {
> > +    }
> > +  }
> > +}
> >
> > Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=213120&r1=213119&r2=213120&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
> > +++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Wed Jul 16 00:16:52 2014
> > @@ -311,3 +311,102 @@ namespace N {
> >
> >  namespace TypedefNamespace { typedef int F; };
> >  TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; //
> expected-error {{'F' (aka 'int') is not a class, namespace, or scoped
> enumeration}}
> > +
> > +namespace PR18587 {
> > +
> > +struct C1 {
> > +  int a, b, c;
> > +  typedef int C2;
> > +  struct B1 {
> > +    struct B2 {
> > +      int a, b, c;
> > +    };
> > +  };
> > +};
> > +struct C2 { static const unsigned N1 = 1; };
> > +struct B1 {
> > +  enum E1 { B2 = 2 };
> > +  static const int B3 = 3;
> > +};
> > +const int N1 = 2;
> > +
> > +// Function declarators
> > +struct S1a { int f(C1::C2); };
> > +struct S1b { int f(C1:C2); };  // expected-error{{unexpected ':' in
> nested name specifier; did you mean '::'?}}
> > +
> > +struct S2a {
> > +  C1::C2 f(C1::C2);
> > +};
> > +struct S2c {
> > +  C1::C2 f(C1:C2);  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +};
> > +
> > +struct S3a {
> > +  int f(C1::C2), C2 : N1;
> > +  int g : B1::B2;
> > +};
> > +struct S3b {
> > +  int g : B1:B2;  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +};
> > +
> > +// Inside square brackets
> > +struct S4a {
> > +  int f[C2::N1];
> > +};
> > +struct S4b {
> > +  int f[C2:N1];  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +};
> > +
> > +struct S5a {
> > +  int f(int xx[B1::B3 ? C2::N1 : B1::B2]);
> > +};
> > +struct S5b {
> > +  int f(int xx[B1::B3 ? C2::N1 : B1:B2]);  //
> expected-error{{unexpected ':' in nested name specifier; did you mean
> '::'?}}
> > +};
> > +struct S5c {
> > +  int f(int xx[B1:B3 ? C2::N1 : B1::B2]);  //
> expected-error{{unexpected ':' in nested name specifier; did you mean
> '::'?}}
> > +};
> > +
> > +// Bit fields
> > +struct S6a {
> > +  C1::C2 m1 : B1::B2;
> > +};
> > +struct S6c {
> > +  C1::C2 m1 : B1:B2;  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +};
> > +struct S6d {
> > +  int C2:N1;
> > +};
> > +struct S6e {
> > +  static const int N = 3;
> > +  B1::E1 : N;
> > +};
> > +struct S6g {
> > +  C1::C2 : B1:B2;  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +  B1::E1 : B1:B2;  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +};
> > +
> > +// Template parameters
> > +template <int N> struct T1 {
> > +  int a,b,c;
> > +  static const unsigned N1 = N;
> > +  typedef unsigned C1;
> > +};
> > +T1<C2::N1> var_1a;
> > +T1<C2:N1> var_1b;  // expected-error{{unexpected ':' in nested name
> specifier; did you mean '::'?}}
> > +template<int N> int F() {}
> > +int (*X1)() = (B1::B2 ? F<1> : F<2>);
> > +int (*X2)() = (B1:B2 ? F<1> : F<2>);  // expected-error{{unexpected ':'
> in nested name specifier; did you mean '::'?}}
> > +
> > +// Bit fields + templates
> > +struct S7a {
> > +  T1<B1::B2>::C1 m1 : T1<B1::B2>::N1;
> > +};
> > +struct S7b {
> > +  T1<B1:B2>::C1 m1 : T1<B1::B2>::N1;  // expected-error{{unexpected ':'
> in nested name specifier; did you mean '::'?}}
> > +};
> > +struct S7c {
> > +  T1<B1::B2>::C1 m1 : T1<B1:B2>::N1;  // expected-error{{unexpected ':'
> in nested name specifier; did you mean '::'?}}
> > +};
> > +
> > +}
> >
> >
> > _______________________________________________
> > 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/20140717/cacf7686/attachment.html>


More information about the cfe-commits mailing list