r199970 - Update page on clang diagnostics to contrast to GCC 4.9 instead of 4.2. A lot

Nico Weber thakis at chromium.org
Thu Jan 23 20:08:42 PST 2014


They have at least a flag to turn it on:
http://llvm.org/viewvc/llvm-project?view=revision&revision=179728

Maybe it's not on by default though?


On Thu, Jan 23, 2014 at 8:04 PM, Sean Silva <silvas at purdue.edu> wrote:

> Does GCC's output still not have color?
>
> -- Sean Silva
>
>
> On Thu, Jan 23, 2014 at 10:13 PM, Richard Smith <
> richard-llvm at metafoo.co.uk> wrote:
>
>> Author: rsmith
>> Date: Thu Jan 23 21:13:34 2014
>> New Revision: 199970
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=199970&view=rev
>> Log:
>> Update page on clang diagnostics to contrast to GCC 4.9 instead of 4.2. A
>> lot
>> of the differences we identified here have been fixed by improvements in
>> GCC.
>>
>> Modified:
>>     cfe/trunk/www/diagnostics.html
>>
>> Modified: cfe/trunk/www/diagnostics.html
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/www/diagnostics.html?rev=199970&r1=199969&r2=199970&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/www/diagnostics.html (original)
>> +++ cfe/trunk/www/diagnostics.html Thu Jan 23 21:13:34 2014
>> @@ -7,10 +7,14 @@
>>    <link type="text/css" rel="stylesheet" href="menu.css">
>>    <link type="text/css" rel="stylesheet" href="content.css">
>>    <style type="text/css">
>> -  .warn { color:magenta; }
>> -  .err { color:red; }
>> -  .snip { color:darkgreen; }
>> -  .point { color:blue; }
>> +  .loc { font-weight: bold; }
>> +  .err { color:red; font-weight: bold; }
>> +  .warn { color:magenta; font-weight: bold; }
>> +  .note { color:gray; font-weight: bold; }
>> +  .msg { font-weight: bold; }
>> +  .cmd { font-style: italic; }
>> +  .snip { }
>> +  .point { color:green; font-weight: bold; }
>>    </style>
>>  </head>
>>  <body>
>> @@ -29,10 +33,7 @@ friendly.  As far as a command-line comp
>>  making the diagnostics (error and warning messages) generated by the
>> compiler
>>  be as useful as possible.  There are several ways that we do this.  This
>> section
>>  talks about the experience provided by the command line compiler,
>> contrasting
>> -Clang output to GCC 4.2's output in several examples.
>> -<!--
>> -Other clients
>> -that embed Clang and extract equivalent information through internal
>> APIs.-->
>> +Clang output to GCC 4.9's output in some cases.
>>  </p>
>>
>>  <h2>Column Numbers and Caret Diagnostics</h2>
>> @@ -41,25 +42,35 @@ that embed Clang and extract equivalent
>>  information. The clang command-line compiler driver uses this information
>>  to print "point diagnostics".
>>  (IDEs can use the information to display in-line error markup.)
>> -Precise error location in the source is a feature provided by many
>> commercial
>> -compilers, but is generally missing from open source
>> -compilers.  This is nice because it makes it very easy to understand
>> exactly
>> -what is wrong in a particular piece of code</p>
>> +This is nice because it makes it very easy to understand exactly
>> +what is wrong in a particular piece of code.</p>
>>
>> -<p>The point (the blue "^" character) exactly shows where the problem
>> is, even
>> +<p>The point (the green "^" character) exactly shows where the problem
>> is, even
>>  inside of a string.  This makes it really easy to jump to the problem and
>> -helps when multiple instances of the same character occur on a line.
>> (We'll
>> +helps when multiple instances of the same character occur on a line.
>> (We'll
>>  revisit this more in following examples.)</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only -Wformat format-strings.c</b>
>> -  format-strings.c:91: warning: too few arguments for format
>> -  $ <b>clang -fsyntax-only format-strings.c</b>
>> -  format-strings.c:91:13: <span class="warn">warning:</span> '.*'
>> specified field precision is missing a matching 'int' argument
>> -  <span class="snip">  printf("%.*d");</span>
>> +  $ <span class="cmd">gcc-4.9 -fsyntax-only -Wformat
>> format-strings.c</span>
>> +  format-strings.c: In function 'void f()':
>> +  format-strings.c:91:16: warning: field precision specifier '.*'
>> expects a matching 'int' argument [-Wformat=]
>> +     printf("%.*d");
>> +                  ^
>> +  format-strings.c:91:16: warning: format '%d' expects a matching 'int'
>> argument [-Wformat=]
>> +  $ <span class="cmd">clang -fsyntax-only format-strings.c</span>
>> +  <span class="loc">format-strings.c:91:13:</span> <span
>> class="warn">warning:</span> <span class="msg">'.*' specified field
>> precision is missing a matching 'int' argument</span>
>> +  <span class="snip" >  printf("%.*d");</span>
>>    <span class="point">            ^</span>
>>  </pre>
>>
>> +<p>Note that modern versions of GCC have followed Clang's lead, and are
>> +now able to give a column for a diagnostic, and include a snippet of
>> source
>> +text in the result. However, Clang's column number is much more accurate,
>> +pointing at the problematic format specifier, rather than the <tt>)</tt>
>> +character the parser had reached when the problem was detected.
>> +Also, Clang's diagnostic is colored by default, making it easier to
>> +distinguish from nearby text.</p>
>> +
>>  <h2>Range Highlighting for Related Text</h2>
>>
>>  <p>Clang captures and accurately tracks range information for
>> expressions,
>> @@ -74,11 +85,14 @@ Range information is very useful for
>>  cases involving precedence issues and many other cases.</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  t.c:7: error: invalid operands to binary + (have 'int' and 'struct A')
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:7:39: <span class="err">error:</span> invalid operands to binary
>> expression ('int' and 'struct A')
>> -  <span class="snip">  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42
>> + SomeA.X : SomeA.X);</span>
>> +  $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span>
>> +  t.c: In function 'int f(int, int)':
>> +  t.c:7:39: error: invalid operands to binary + (have 'int' and 'struct
>> A')
>> +     return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X :
>> SomeA.X);
>> +                                         ^
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:7:39:</span> <span class="err">error:</span>
>> <span class="msg">invalid operands to binary expression ('int' and 'struct
>> A')</span>
>> +  <span class="snip" >  return y + func(y ? ((SomeA.X + 40) + SomeA) /
>> 42 + SomeA.X : SomeA.X);</span>
>>    <span class="point">                       ~~~~~~~~~~~~~~ ^
>> ~~~~~</span>
>>  </pre>
>>
>> @@ -90,62 +104,24 @@ why.  In the example above, we tell you
>>  the left and right hand sides, and we don't repeat what is obvious from
>> the
>>  point (e.g., that this is a "binary +").</p>
>>
>> -<p>Many other examples abound. In the following example, not only do we
>> tell you that there is a problem with the *
>> +<p>Many other examples abound. In the following example, not only do we
>> tell you
>> +that there is a problem with the <tt>*</tt>
>>  and point to it, we say exactly why and tell you what the type is (in
>> case it is
>>  a complicated subexpression, such as a call to an overloaded function).
>>  This
>>  sort of attention to detail makes it much easier to understand and fix
>> problems
>>  quickly.</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  t.c:5: error: invalid type argument of 'unary *'
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:5:11: <span class="err">error:</span> indirection requires pointer
>> operand ('int' invalid)
>> -  <span class="snip">  int y = *SomeA.X;</span>
>> +  $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span>
>> +  t.c:5:11: error: invalid type argument of unary '*' (have 'int')
>> +    return *SomeA.X;
>> +           ^
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:5:11:</span> <span class="err">error:</span>
>> <span class="msg">indirection requires pointer operand ('int'
>> invalid)</span>
>> +  <span class="snip" >  int y = *SomeA.X;</span>
>>    <span class="point">          ^~~~~~~~</span>
>>  </pre>
>>
>> -<h2>No Pretty Printing of Expressions in Diagnostics</h2>
>> -
>> -<p>Since Clang has range highlighting, it never needs to pretty print
>> your code
>> -back out to you.  GCC can produce inscrutible error messages in some
>> cases when
>> -it tries to do this.  In this example P and Q have type "int*":</p>
>> -
>> -<pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  #'exact_div_expr' not supported by pp_c_expression#'t.c:12: error:
>> called object  is not a function
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:12:8: <span class="err">error:</span> called object type 'int' is
>> not a function or function pointer
>> -  <span class="snip">  (P-Q)();</span>
>> -  <span class="point">  ~~~~~^</span>
>> -</pre>
>> -
>> -<p>This can be particularly bad in G++, which often emits errors
>> -   containing lowered vtable references.  For example:</p>
>> -
>> -<pre>
>> -  $ <b>cat t.cc</b>
>> -  struct a {
>> -    virtual int bar();
>> -  };
>> -
>> -  struct foo : public virtual a {
>> -  };
>> -
>> -  void test(foo *P) {
>> -    return P->bar() + *P;
>> -  }
>> -  $ <b>gcc-4.2 t.cc</b>
>> -  t.cc: In function 'void test(foo*)':
>> -  t.cc:9: error: no match for 'operator+' in '(((a*)P) + (*(long
>> int*)(P->foo::<anonymous>.a::_vptr$a +
>> -0x00000000000000020)))->a::bar() + * P'
>> -  t.cc:9: error: return-statement with a value, in function returning
>> 'void'
>> -  $ <b>clang t.cc</b>
>> -  t.cc:9:18: <span class="err">error:</span> invalid operands to binary
>> expression ('int' and 'foo')
>> -  <span class="snip">  return P->bar() + *P;</span>
>> -  <span class="point">         ~~~~~~~~ ^ ~~</span>
>> -</pre>
>> -
>> -
>>  <h2>Typedef Preservation and Selective Unwrapping</h2>
>>
>>  <p>Many programmers use high-level user defined types, typedefs, and
>> other
>> @@ -156,15 +132,11 @@ trivial types and it is important to str
>>  is going on.  Clang aims to handle both cases well.<p>
>>
>>  <p>The following example shows where it is important to preserve
>> -a typedef in C. Here the type printed by GCC isn't even valid, but if
>> the error
>> -were about a very long and complicated type (as often happens in C++)
>> the error
>> -message would be ugly just because it was long and hard to read.</p>
>> +a typedef in C.</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  t.c:15: error: invalid operands to binary / (have 'float __vector__'
>> and 'const int *')
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:15:11: <span class="err">error:</span> can't convert between
>> vector values of different size ('__m128' and 'int const *')
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:15:11:</span> <span class="err">error:</span>
>> <span class="msg">can't convert between vector values of different size
>> ('__m128' and 'int const *')</span>
>>    <span class="snip">  myvec[1]/P;</span>
>>    <span class="point">  ~~~~~~~~^~</span>
>>  </pre>
>> @@ -174,10 +146,8 @@ underlying details of a typedef. If the
>>  system "pid_t" typedef is defined, Clang helpfully displays it with
>> "aka".</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  t.c:13: error: request for member 'x' in something not a structure or
>> union
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:13:9: <span class="err">error:</span> member reference base type
>> 'pid_t' (aka 'int') is not a structure or union
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:13:9:</span> <span class="err">error:</span>
>> <span class="msg">member reference base type 'pid_t' (aka 'int') is not a
>> structure or union</span>
>>    <span class="snip">  myvar = myvar.x;</span>
>>    <span class="point">          ~~~~~ ^</span>
>>  </pre>
>> @@ -202,13 +172,11 @@ void addHTTPService(servers::Server cons
>>  </pre>
>>  </blockquote>
>>
>> -<p>and then compile it, we see that Clang is both providing more
>> accurate information and is retaining the types as written by the user
>> (e.g., "servers::Server", "::services::WebService"):
>> +<p>and then compile it, we see that Clang is both providing accurate
>> information and is retaining the types as written by the user (e.g.,
>> "servers::Server", "::services::WebService"):
>>
>>  <pre>
>> -  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
>> -  t.cpp:9: error: no match for 'operator+=' in 'server += http'
>> -  $ <b>clang -fsyntax-only t.cpp</b>
>> -  t.cpp:9:10: <span class="err">error:</span> invalid operands to binary
>> expression ('servers::Server const' and '::services::WebService const *')
>> +  $ <span class="cmd">clang -fsyntax-only t.cpp</span>
>> +  <span class="loc">t.cpp:9:10:</span> <span class="err">error:</span>
>> <span class="msg">invalid operands to binary expression ('servers::Server
>> const' and '::services::WebService const *')</span>
>>      <span class="snip">server += http;</span>
>>      <span class="point">~~~~~~ ^  ~~~~</span>
>>  </pre>
>> @@ -216,10 +184,8 @@ void addHTTPService(servers::Server cons
>>  <p>Naturally, type preservation extends to uses of templates, and Clang
>> retains information about how a particular template specialization (like
>> <code>std::vector<Real></code>) was spelled within the source code.
>> For example:</p>
>>
>>  <pre>
>> -  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
>> -  t.cpp:12: error: no match for 'operator=' in 'str = vec'
>> -  $ <b>clang -fsyntax-only t.cpp</b>
>> -  t.cpp:12:7: <span class="err">error:</span> incompatible type
>> assigning 'vector<Real>', expected 'std::string' (aka 'class
>> std::basic_string<char>')
>> +  $ <span class="cmd">clang -fsyntax-only t.cpp</span>
>> +  <span class="loc">t.cpp:12:7:</span> <span class="err">error:</span>
>> <span class="msg">incompatible type assigning 'vector<Real>',
>> expected 'std::string' (aka 'class std::basic_string<char>')</span>
>>      <span class="snip">str = vec</span>;
>>          <span class="point">^ ~~~</span>
>>  </pre>
>> @@ -237,14 +203,14 @@ code should be removed, then replaced wi
>>  point line (".x =" or ".y =", respectively).</p>
>>
>>  <pre>
>> -  $ <b>clang t.c</b>
>> -  t.c:5:28: <span class="warn">warning:</span> use of GNU old-style
>> field designator extension
>> +  $ <span class="cmd">clang t.c</span>
>> +  <span class="loc">t.c:5:28:</span> <span class="warn">warning:</span>
>> <span class="msg">use of GNU old-style field designator extension</span>
>>    <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span>
>> -                          <span class="err">~~</span> <span
>> class="point">^</span>
>> +                          <span class="err">~~</span> <span
>> class="msg"><span class="point">^</span></span>
>>                            <span class="snip">.x = </span>
>> -  t.c:5:36: <span class="warn">warning:</span> use of GNU old-style
>> field designator extension
>> +  <span class="loc">t.c:5:36:</span> <span class="warn">warning:</span>
>> <span class="msg">use of GNU old-style field designator extension</span>
>>    <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span>
>> -                                  <span class="err">~~</span> <span
>> class="point">^</span>
>> +                                  <span class="err">~~</span> <span
>> class="msg"><span class="point">^</span></span>
>>                                    <span class="snip">.y = </span>
>>  </pre>
>>
>> @@ -256,8 +222,8 @@ Clang provides the fix--add <code>templa
>>  diagnostic.<p>
>>
>>  <pre>
>> -  $ <b>clang t.cpp</b>
>> -  t.cpp:9:3: <span class="err">error:</span> template specialization
>> requires 'template<>'
>> +  $ <span class="cmd">clang t.cpp</span>
>> +  <span class="loc">t.cpp:9:3:</span> <span class="err">error:</span>
>> <span class="msg">template specialization requires 'template<>'</span>
>>      struct iterator_traits<file_iterator> {
>>      <span class="point">^</span>
>>      <span class="snip">template<> </span>
>> @@ -273,15 +239,15 @@ printed as an indented text tree.</p>
>>
>>  Default: template diff with type elision
>>  <pre>
>> -t.cc:4:5: <span class="note">note:</span> candidate function not viable:
>> no known conversion from 'vector<map<[...], <span
>> class="template-highlight">float</span>>>' to
>> 'vector<map<[...], <span
>> class="template-highlight">double</span>>>' for 1st argument;
>> +<span class="loc">t.cc:4:5:</span> <span class="note">note:</span>
>> candidate function not viable: no known conversion from
>> 'vector<map<[...], <span
>> class="template-highlight">float</span>>>' to
>> 'vector<map<[...], <span
>> class="template-highlight">double</span>>>' for 1st argument;
>>  </pre>
>>  -fno-elide-type: template diff without elision
>>  <pre>
>> -t.cc:4:5: <span class="note">note:</span> candidate function not viable:
>> no known conversion from 'vector<map<int, <span
>> class="template-highlight">float</span>>>' to 'vector<map<int,
>> <span class="template-highlight">double</span>>>' for 1st argument;
>> +<span class="loc">t.cc:4:5:</span> <span class="note">note:</span>
>> candidate function not viable: no known conversion from
>> 'vector<map<int, <span
>> class="template-highlight">float</span>>>' to 'vector<map<int,
>> <span class="template-highlight">double</span>>>' for 1st argument;
>>  </pre>
>>  -fdiagnostics-show-template-tree: template tree printing with elision
>>  <pre>
>> -t.cc:4:5: <span class="note">note:</span> candidate function not viable:
>> no known conversion for 1st argument;
>> +<span class="loc">t.cc:4:5:</span> <span class="note">note:</span>
>> candidate function not viable: no known conversion for 1st argument;
>>    vector<
>>      map<
>>        [...],
>> @@ -289,7 +255,7 @@ t.cc:4:5: <span class="note">note:</span
>>  </pre>
>>  -fdiagnostics-show-template-tree -fno-elide-type: template tree printing
>> with no elision
>>  <pre>
>> -t.cc:4:5: <span class="note">note:M</span> candidate function not
>> viable: no known conversion for 1st argument;
>> +<span class="loc">t.cc:4:5:</span> <span class="note">note:</span>
>> candidate function not viable: no known conversion for 1st argument;
>>    vector<
>>      map<
>>        int,
>> @@ -306,14 +272,11 @@ nested range information for diagnostics
>>  and also shows how some of the other pieces work in a bigger example.</p>
>>
>>  <pre>
>> -  $ <b>gcc-4.2 -fsyntax-only t.c</b>
>> -  t.c: In function 'test':
>> -  t.c:80: error: invalid operands to binary < (have 'struct mystruct'
>> and 'float')
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:80:3: <span class="err">error:</span> invalid operands to binary
>> expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka
>> 'float'))
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:80:3:</span> <span class="err">error:</span>
>> <span class="msg">invalid operands to binary expression ('typeof(P)' (aka
>> 'struct mystruct') and 'typeof(F)' (aka 'float'))</span>
>>    <span class="snip">  X = MYMAX(P, F);</span>
>>    <span class="point">      ^~~~~~~~~~~</span>
>> -  t.c:76:94: note: expanded from:
>> +  <span class="loc">t.c:76:94:</span> <span class="note">note:</span>
>> expanded from:
>>    <span class="snip">#define MYMAX(A,B)    __extension__ ({
>> __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a;
>> })</span>
>>    <span class="point">
>>                                       ~~~ ^ ~~~</span>
>>  </pre>
>> @@ -322,14 +285,14 @@ and also shows how some of the other pie
>>  implements the "wwopen" class of APIs):</p>
>>
>>  <pre>
>> -  $ <b>clang -fsyntax-only t.c</b>
>> -  t.c:22:2: <span class="warn">warning:</span> type specifier missing,
>> defaults to 'int'
>> +  $ <span class="cmd">clang -fsyntax-only t.c</span>
>> +  <span class="loc">t.c:22:2:</span> <span class="warn">warning:</span>
>> <span class="msg">type specifier missing, defaults to 'int'</span>
>>    <span class="snip">        ILPAD();</span>
>>    <span class="point">        ^</span>
>> -  t.c:17:17: note: expanded from:
>> +  <span class="loc">t.c:17:17:</span> <span class="note">note:</span>
>> expanded from:
>>    <span class="snip">#define ILPAD() PAD((NROW - tt.tt_row) * 10)    /*
>> 1 ms per char */</span>
>>    <span class="point">                ^</span>
>> -  t.c:14:2: note: expanded from:
>> +  <span class="loc">t.c:14:2:</span> <span class="note">note:</span>
>> expanded from:
>>    <span class="snip">        register i; \</span>
>>    <span class="point">        ^</span>
>>  </pre>
>> @@ -342,63 +305,65 @@ macros that in simple ones.</p>
>>  <p>Finally, we have put a lot of work polishing the little things,
>> because
>>  little things add up over time and contribute to a great user
>> experience.</p>
>>
>> -<p>The following example shows a trivial little tweak, where we tell you
>> to put the semicolon at
>> -the end of the line that is missing it (line 4) instead of at the
>> beginning of
>> -the following line (line 5).  This is particularly important with fixit
>> hints
>> -and point diagnostics, because otherwise you don't get the important
>> context.
>> -</p>
>> -
>> -<pre>
>> -  $ <b>gcc-4.2 t.c</b>
>> -  t.c: In function 'foo':
>> -  t.c:5: error: expected ';' before '}' token
>> -  $ <b>clang t.c</b>
>> -  t.c:4:8: <span class="err">error:</span> expected ';' after expression
>> -  <span class="snip">  bar()</span>
>> -  <span class="point">       ^</span>
>> -  <span class="point">       ;</span>
>> -</pre>
>> -
>> -<p>The following example shows much better error recovery than GCC. The
>> message coming out
>> -of GCC is completely useless for diagnosing the problem. Clang tries
>> much harder
>> -and produces a much more useful diagnosis of the problem.</p>
>> -
>> -<pre>
>> -  $ <b>gcc-4.2 t.c</b>
>> -  t.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before
>> '*' token
>> -  $ <b>clang t.c</b>
>> -  t.c:3:1: <span class="err">error:</span> unknown type name 'foo_t'
>> -  <span class="snip">foo_t *P = 0;</span>
>> -  <span class="point">^</span>
>> -</pre>
>> -
>>  <p>The following example shows that we recover from the simple case of
>>  forgetting a ; after a struct definition much better than GCC.</p>
>>
>>  <pre>
>> -  $ <b>cat t.cc</b>
>> +  $ <span class="cmd">cat t.cc</span>
>>    template<class T>
>> -  class a {}
>> -  class temp {};
>> -  a<temp> b;
>> -  struct b {
>> +  class a {};
>> +  struct b {}
>> +  a<int> c;
>> +  $ <span class="cmd">gcc-4.9 t.cc</span>
>> +  t.cc:4:8: error: invalid declarator before 'c'
>> +   a<int> c;
>> +           ^
>> +  $ <span class="cmd">clang t.cc</span>
>> +  <span class="loc">t.cc:3:12:</span> <span class="err">error:</span>
>> <span class="msg">expected ';' after struct</span>
>> +  <span class="snip" >struct b {}</span>
>> +  <span class="point">           ^</span>
>> +  <span class="point">           ;</span>
>> +</pre>
>> +
>> +<p>The following example shows that we diagnose and recover from a
>> missing
>> +<tt>typename</tt> keyword well, even in complex circumstances where GCC
>> +cannot cope.</p>
>> +
>> +<pre>
>> +  $ <span class="cmd">cat t.cc</span>
>> +  template<class T> void f(T::type) { }
>> +  struct A { };
>> +  void g()
>> +  {
>> +      A a;
>> +      f<A>(a);
>>    }
>> -  $ <b>gcc-4.2 t.cc</b>
>> -  t.cc:3: error: multiple types in one declaration
>> -  t.cc:4: error: non-template type 'a' used as a template
>> -  t.cc:4: error: invalid type in declaration before ';' token
>> -  t.cc:6: error: expected unqualified-id at end of input
>> -  $ <b>clang t.cc</b>
>> -  t.cc:2:11: <span class="err">error:</span> expected ';' after class
>> -  <span class="snip">class a {}</span>
>> -  <span class="point">          ^</span>
>> -  <span class="point">          ;</span>
>> -  t.cc:6:2: <span class="err">error:</span> expected ';' after struct
>> -  <span class="snip">}</span>
>> -  <span class="point"> ^</span>
>> -  <span class="point"> ;</span>
>> +  $ <span class="cmd">gcc-4.9 t.cc</span>
>> +  t.cc:1:33: error: variable or field 'f' declared void
>> +   template<class T> void f(T::type) { }
>> +                                   ^
>> +  t.cc: In function 'void g()':
>> +  t.cc:6:5: error: 'f' was not declared in this scope
>> +       f<A>(a);
>> +       ^
>> +  t.cc:6:8: error: expected primary-expression before '>' token
>> +       f<A>(a);
>> +          ^
>> +  $ <span class="cmd">clang t.cc</span>
>> +  <span class="loc">t.cc:1:26:</span> <span class="error">error:</span>
>> <span class="msg">missing 'typename' prior to dependent type name
>> 'T::type'</span>
>> +  <span class="snip" >template<class T> void f(T::type) { }</span>
>> +  <span class="point">                         ^~~~~~~</span>
>> +  <span class="point">                         typename </span>
>> +  <span class="loc">t.cc:6:5:</span> <span class="error">error:</span>
>> <span class="msg">no matching function for call to 'f'</span>
>> +  <span class="snip" >    f<A>(a);</span>
>> +  <span class="point">    ^~~~</span>
>> +  <span class="loc">t.cc:1:24:</span> <span class="note">note:</span>
>> <span class="msg">candidate template ignored: substitution failure [with T
>> = A]: no type named 'type' in 'A'</span>
>> +  <span class="snip" >template<class T> void f(T::type) { }</span>
>> +  <span class="point">                       ^    ~~~~</span>
>>  </pre>
>>
>> +
>> +
>>  <p>While each of these details is minor, we feel that they all add up to
>> provide
>>  a much more polished experience.</p>
>>
>>
>>
>> _______________________________________________
>> 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/20140123/413d0191/attachment.html>


More information about the cfe-commits mailing list