Skip to content

Commit

Permalink
[Clang][AST] Fix a crash on attaching doc comments (#78716)
Browse files Browse the repository at this point in the history
This crash is basically caused by calling
`ASTContext::getRawCommentForDeclNoCacheImp` with its input arguments
`RepresentativeLocForDecl` and `CommentsInTheFile` refering to different
files. A reduced reproducer is provided in this patch.

After the source locations for instantiations of funtion template are
corrected in the commit 256a0b2, the
variable `CommitsInThisFile` in the function
`ASTContext::attachCommentsToJustParsedDecls` would refer to the source
file rather than the header file for implicit function template
instantiation. Therefore, in the first loop in
`ASTContext::attachCommentsToJustParsedDecls`, `D` should also be
adjusted for relevant scenarios like the second loop.

Fixes #67979 
Fixes #68524
Fixes #70550
  • Loading branch information
chenshanzhi committed Jan 29, 2024
1 parent 14a1510 commit 5f4ee5a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
6 changes: 5 additions & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,11 @@ void ASTContext::attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,
return;

FileID File;
for (Decl *D : Decls) {
for (const Decl *D : Decls) {
if (D->isInvalidDecl())
continue;

D = &adjustDeclToTemplate(*D);
SourceLocation Loc = D->getLocation();
if (Loc.isValid()) {
// See if there are any new comments that are not attached to a decl.
Expand Down
30 changes: 30 additions & 0 deletions clang/test/AST/ast-crash-doc-function-template.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: rm -rf %t
// RUN: split-file %s %t

// RUN: %clang_cc1 -x c++ -Wdocumentation -fsyntax-only -ast-dump-all %t/t.cpp

//--- t.h
/// MyClass in the header file
class MyClass {
public:
template <typename T>
void Foo() const;

/// Bar
void Bar() const;
};

//--- t.cpp
#include "t.h"

/// MyClass::Bar: Foo<int>() is implicitly instantiated and called here.
void MyClass::Bar() const {
Foo<int>();
}

/// MyClass::Foo
template <typename T>
void MyClass::Foo() const {
}

// CHECK: TranslationUnitDecl

0 comments on commit 5f4ee5a

Please sign in to comment.