[cfe-dev] Diagnostic.h : Diagnostic::Report line 836

Michael Mullin masmullin at gmail.com
Tue Nov 2 09:46:35 PDT 2010


The following code is adapted from an online clang tutorial.  It will seg
fault if it Lexes itself.

The seg fault happens somewhere in the vicinity of Preprocessor.h Diag()
(line 625/631) and the function that I posted below.

My compiler could be choosing not to inline the function, thus the
DiagnosticBuilder(this) that is created will be destroyed as the function is
popped off the call-stack.  Thus using the return value of this function
will cause a fault.

Here is the output of g++ --version on my machine

$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

---
/* Title: myclang.cxx */
#include <clang/Basic/Diagnostic.h>
#include <clang/Basic/LangOptions.h>
#include <clang/Basic/TargetOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/SourceManager.h>

#include <clang/Basic/FileManager.h>
#include <clang/Lex/HeaderSearch.h>

#include <clang/Lex/Preprocessor.h>

#include <iostream>

using namespace clang;

int main(void)
{
  Diagnostic diag;

  LangOptions langOp;
  TargetOptions targOps;
  targOps.Triple = LLVM_HOSTTRIPLE;

  TargetInfo *target = TargetInfo::CreateTargetInfo(diag,targOps);

  SourceManager sm(diag);
  FileManager fm;
  HeaderSearch hs(fm);
  Preprocessor pp(diag,langOp,*target,sm,hs);
  const FileEntry* file = fm.getFile("myclang.cxx");

  FileID fi = sm.createMainFileID(file);

  pp.EnterSourceFile(fi,0,SourceLocation());

  Token Tok;

  do {
    pp.Lex(Tok);  // read one token
    if (diag.hasErrorOccurred())  // stop lexing/pp on error
      break;

    pp.DumpToken(Tok);  // outputs to cerr
    std::cerr << std::endl;
  } while (Tok.isNot(tok::eof));

  delete target;

  return 0;
}
---


On Tue, Nov 2, 2010 at 11:21 AM, Douglas Gregor <dgregor at apple.com> wrote:

>
> On Nov 1, 2010, at 10:24 PM, Michael Mullin wrote:
>
> Hello
>
> I believe I have found a bug in Diagnostic.h
>
> 00836 <http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html#aa0f6707a3958ae818534b2aca4d3b7af> inline DiagnosticBuilder <http://clang.llvm.org/doxygen/classclang_1_1DiagnosticBuilder.html> Diagnostic::Report <http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html#aa0f6707a3958ae818534b2aca4d3b7af>(FullSourceLoc <http://clang.llvm.org/doxygen/classclang_1_1FullSourceLoc.html> Loc <http://clang.llvm.org/doxygen/classclang_1_1Loc.html>, unsigned DiagID){
>
> 00837   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
> 00838   CurDiagLoc = Loc;
> 00839   CurDiagID = DiagID;
>
> 00840   return DiagnosticBuilder <http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html#a97ec9151bbe20af5173173f6de89f3bb>(this);
>
> 00841 }
>
> 840 will cause a segmentation fault if the return value is used by the calling function.
>
>
> It seems to be working fairly well... why do you think there's an issue
> here?
>
> - Doug
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20101102/da0ee334/attachment.html>


More information about the cfe-dev mailing list