llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.26k stars 12.09k forks source link

This is a bug in ASTContext.cpp: ASTContext::getTypeInfoImpl(const Type *T) ? #73901

Open xytywh opened 12 months ago

xytywh commented 12 months ago

The source code snippets is as follows:

test.c


unsigned int test(int count, ...) {
    unsigned int ret = 0;
    va_list args;
    va_start(args, count);

    for (int i = 0; i < count; ++i) {
        int value = va_arg(args, int);
        // handle value
    }

    va_end(args);
    return ret;
}

int main() {
   return 0;
}

I write a CSA checker to find some bugs,when I use PreStmt:

void xxChecker::checkPreStmt(const Stmt *S, CheckerContext &C) const {
  auto expr = dyn_cast<Expr>(S);
  expr = expr->IgnoreImpCasts();
  if (expr) {
    TypeInfo FieldInfo =
        C.getASTContext().getTypeInfo(expr->getType().getTypePtr());
    unsigned int size = FieldInfo.Width / 8;
}

in Ubuntu 20, when I run command: path-to/bin/clang -cc1 -analyze -analyzer-checker=aboveChecker -I/usr/include -I/usr/include/x86_64-linux-gnu/ -I/usr/lib/gcc/x86_64-linux-gnu/9/include/ test.c , there is an error, finally crash in :

ASTContext.cpp:  ASTContext::getTypeInfoImpl(const Type *T)
...
...
 case Type::Builtin:
    switch (cast<BuiltinType>(T)->getKind()) {
    default: llvm_unreachable("Unknown builtin type!"); // here crash

I found when PreStmt deal with `va_start(args, count);' in test.c, 'expr->getType().getTypePtr()' incheckPreStmt dump() is:


BuiltinType 0x5555556c6d10 '<builtin fn type>'
'''

so, in  `ASTContext::getTypeInfoImpl`, cast<BuiltinType>(T)->getKind() will be `BuiltinType::BuiltinFn', is this a bug? or should deal with this kind of type, like add a new case BuiltinType::BuiltinFn is a better solution? 
llvmbot commented 12 months ago

@llvm/issue-subscribers-clang-frontend

Author: None (xytywh)

The source code snippets is as follows: ### test.c ```#include <stdarg.h> unsigned int test(int count, ...) { unsigned int ret = 0; va_list args; va_start(args, count); for (int i = 0; i < count; ++i) { int value = va_arg(args, int); // handle value } va_end(args); return ret; } int main() { return 0; } ``` I write a CSA checker to find some bugs,when I use PreStmt: ``` void xxChecker::checkPreStmt(const Stmt *S, CheckerContext &C) const { auto expr = dyn_cast<Expr>(S); expr = expr->IgnoreImpCasts(); if (expr) { TypeInfo FieldInfo = C.getASTContext().getTypeInfo(expr->getType().getTypePtr()); unsigned int size = FieldInfo.Width / 8; } ``` in Ubuntu 20, when I run command: `path-to/bin/clang -cc1 -analyze -analyzer-checker=aboveChecker -I/usr/include -I/usr/include/x86_64-linux-gnu/ -I/usr/lib/gcc/x86_64-linux-gnu/9/include/ test.c` , there is an error, finally crash in : ``` ASTContext.cpp: ASTContext::getTypeInfoImpl(const Type *T) ... ... case Type::Builtin: switch (cast<BuiltinType>(T)->getKind()) { default: llvm_unreachable("Unknown builtin type!"); // here crash ``` I found when PreStmt deal with `va_start(args, count);' in test.c, 'expr->getType().getTypePtr()' incheckPreStmt dump() is: ``` BuiltinType 0x5555556c6d10 '<builtin fn type>' ''' so, in `ASTContext::getTypeInfoImpl`, cast<BuiltinType>(T)->getKind() will be `BuiltinType::BuiltinFn', is this a bug? or should deal with this kind of type, like add a new case BuiltinType::BuiltinFn is a better solution?