<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/95584>95584</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `getSizeExpr` of `ArrayConstantType` returns `NULL` for `char v[sizeof(a)];`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          giulianobelinassi
      </td>
    </tr>
</table>

<pre>
    **Abstract:** Attempting to get the `Expr` that generated the number of elements of a array `VarDecl` via `type->getSizeExpr();`  results in it returning a `NULL` pointer.

---------------------------------------------------------

Assume the following code as test.cpp:

```
#include <clang/Basic/Version.h>
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/RecursiveASTVisitor.h"

using namespace clang;
using namespace llvm;

static const char *const test_file =
"int a;\n"
"char v[sizeof(a)];\n";

static const std::vector<const char *> clang_args =  {"clang", "-O2", "-c", "test.c"};

class TypeVisitor : public RecursiveASTVisitor<TypeVisitor>
{
  public:
 TypeVisitor(ASTUnit *ast)
    : AST(ast)
    {}

  bool VisitConstantArrayType(ConstantArrayType *type)
  {
    const Expr *e = type->getSizeExpr();
    if (e) {
      llvm::outs() << Get_Source_Text(e->getSourceRange()) << '\n';
    } else {
 llvm::outs() << "<<NULL>>" << '\n';
    }
    return true;
 }

  bool VisitVarDecl(VarDecl *decl)
  {
    QualType t = decl->getType();
    if (t->isArrayType()) {
      llvm::outs() << Get_Source_Text(decl->getSourceRange()) << '\n';
    }

    return true;
  }

  private:
  StringRef Get_Source_Text(const SourceRange &range)
  {
    const SourceManager &sm = AST->getSourceManager();
    const LangOptions &lo = AST->getLangOpts();

    SourceLocation start_loc = range.getBegin();
    SourceLocation last_token_loc = range.getEnd();
 SourceLocation end_loc = Lexer::getLocForEndOfToken(last_token_loc, 0, sm, lo);
    SourceRange printable_range(start_loc, end_loc);
    return Lexer::getSourceText(CharSourceRange::getCharRange(printable_range), sm, lo);
  }

  ASTUnit *AST;
};

int main(void)
{
 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
 std::shared_ptr<CompilerInvocation> CInvok;
 std::shared_ptr<PCHContainerOperations> PCHContainerOps;

 IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MFS;

  MFS = IntrusiveRefCntPtr<vfs::InMemoryFileSystem>(new vfs::InMemoryFileSystem);
 MFS->addFile("test.c", 0, MemoryBuffer::getMemBufferCopy(test_file));

  DiagnosticOptions *diagopts = new DiagnosticOptions();

  Diags = CompilerInstance::createDiagnostics(diagopts);

 clang::CreateInvocationOptions CIOpts;
  CIOpts.Diags = Diags;
  CInvok = clang::createInvocation(clang_args, std::move(CIOpts));

 FileManager *FileMgr = new FileManager(FileSystemOptions(), MFS);
 PCHContainerOps = std::make_shared<PCHContainerOperations>();

  auto AST = ASTUnit::LoadFromCompilerInvocation(
      CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 1,
      TU_Complete, false, false, false);

  const DiagnosticsEngine &de = AST->getDiagnostics();

  if (AST == nullptr || de.hasErrorOccurred()) {
    llvm::outs() << "Rejected: compilation error.\n";
    return 1;
  }

  TypeVisitor visitor(AST.get());
 visitor.TraverseDecl(AST->getASTContext().getTranslationUnitDecl());

 return 0;
}
```
Notice the two VarDecls: `int a;` and  `char v[sizeof(a)];`. Notice that the second variable has `sizeof(a)` as the `Expr` that specifies the size of `v`.

Now, compiling with
```
clang++ test.cpp -lclang-cpp -lLLVM
```
will result in a binary `a.out` that outputs:
```
char v[sizeof(a)]
<<NULL>>
```
Which means that for some reason clang lost the `sizeof(a)`. The expected behavior is that `type->getSizeExpr();` should result in an `Expr` that reflects `sizeof(a)`.

The issue is most likely in clang's C parser.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykWN1y4yoSfhpyQ8Ul4_jvwhe2Eu9ObTJzduyZvXRhqSWzg0AFyJmcp99qwJZsazynzqZcigTdH033RzfArRWlAliQ8YqMnx944w7aLErRSMGV3oMUCmUe9jr_WBC2JGy53FtneObIaBka6NI5qGonVEmdpiU46g5AySR5-VkbMkmoO3BHS1BguIPc96qm2oOhuqAgoQLlLL5zyo3hH6j7nZtnyCSqHwXHFvdRwyMZvZTgNuJP8OBsRticjFYoRg3YRjpLhaLCUQOuMQqN8tqfv72-olSthXJgBiR5JskyPB__7l8XZGltU4GfXKGl1O84dKZzoNxSB9YNsrpGp3V0yCSJv_DJRkJlssmBklGaSa5KwtYrbkVG2Po7GCu0GhzI6OVWnrGT_Npo5UDlhK2Xm-03JdzgQBj7iyqprmohwXxS1nGVwW91l5stYeuvkDXGiiMsN9vvwgqnTVfTPxuLLlG8AlvzDGhAGK36e6U8VufO8LSOO5HRTCvraHbghhK2DF_o4F0hJHru-WQuE8pRjiDjVHWmwbzukYxXVvwJuiBsxpFH4-eO7J2hrcsxkKPlETKnDcbqwiQyegmT23FTWrSIUjJdtU5jhKXow8cvrPORte-BL_g9fb6yJJPcWrr9qCH6mZLRktbNXoqM9oSBjNKOcMudaUSlUfdMzS42YbPIIZwXtw7dFNWoH9iHf3bTM12h5R2zKd1rLanHTbUnl1viYsfRCJvdtOGAzvedcTs20xgKzAIo6eNO76aIs6YoKGEzBL5EpJFzGFndOBtUcSmSUUr_AW630Y3JYLeFnw4RTkP51q9clRBHa7UImwZCTS9MINNnCtJCx4B7Y3s-4pvPYqMX_DH2-zHaj5ANqTMNtEJ3QnRKv2wW39DJuW_pD8e_Gy592JyPBIpG98QA90fBoZCwXSacHPj_hKYz_N-LzqVffuG_W8HaiCN30K4lunFGqPIrFD1WBgp3DKSETUyw9B7pg8YbV7wEZP_EVt7py832YtJRosf5AeeVq_JL7YRWFlGkvkKJ_fYKoIUJw7zqjCMItY4bt5M68zh-IoMS3ApKoXqMuNKW3Lqd0z9A3UK8YG26BLjSBpWf1V7hJ5hAFpyFztbavKj8S7FFdMJml0Nhzk3wYSt8St1vaIhQbYRyfC9hFwM1O88alaMZ1wiRPpeGBdjIhfTATZeqJyFsP5H3Zuz5r62-oWYnj2POPgfzpsBg0ay4j9hRi_xMxZaIn5QzDVaZr1Ckyv3hsMg8C14qbZ3I7IsqhQKsgthoW6vOhdMeuIF8V3vNdstxjNFE1RQ_f_xO94_0n6lWjgsF5kuNG0xkM-pf9thr9vbOoU0yx8KGl0_qDSptPtZCwubDOqgQ_G29uVkOb-uNZ18v8n08wmYK3uk9oW5w39YbXKE8z1HAL4zOjuHE5gCxaoqiw7k3qEJLqusPzL-nfVNIjDeTaqPaJoplLnipaxd2Nmj4jdQvMoang9e63mYGAzMD3EGHSZjK42A9eHEDiZqp12wZdLI2_eQTWLsuQsOgteSKopF3vquDn13hY_Y-7_D8KjzRs9JHv58JA_d6FaPWZu-l_yzN2ZudbsJmLQcufYsRXm8ueHFFeQ_Y2sV_wC6snXvr5heR443TmEJOFQJTScB91TxfG131rGI261bwuKBZerM0WRqjwFIanYGvBZcW8CXltWuM54X9l1BxQp-18r1DwtLuONtvO7RFgoMLlOuX20mGqniTyLA25nBVGy9J2ocWNjjRZz62jZS1M5RMUzJNaQ6DA7cvxmjzJcsag4Hp3_38Zmv4Ff4LmcOwLmnmoxBLIkIPrs8znXI0vFcvuieMY_c0gPX4bGiLEGUGW8OPYCzE7WPrseVmi1EP5Y6wOeJsDVc2mIuMijr9qyYanVyUrr5j9GftRBZO4u5d07iBxdRKySQ5nwknCeUqp9h29zw4SQb0DMnD5YaFTKucHrkRWI_pgVvEuVTHAWzvXYitIROFgNCLWlQXKHXE0bqz_qzfkbIhrHhAfhfu0DvreLRcEbY6XzfQR-mbH8P76-v3t17ddyFlvD6hQlFO90Jx4-9h-EA37my4blyNFBz1X2D82o9B-voM04fxn4PIDrQCrmwYs9CGWl0BNcCtViErU6nt-Z7p2u0Duj0AhZ-1XxZ0Dwd-FNpQERH_wmWSPehG5l2fqJsoGigkZK438hdBRGuEtQ0-aYWGS_ED5AfixrBNLU1pzY0FM3jIF6N8PprzB1gMp8PZaD6cD4cPhwUkPHl6SiaTImfZZJwXxTTPp2w0h8kcsvH0QSxYwp6SyfBpOE_Gw2RQJJAnE8iGEz6cPSUT8pRAxYUcYEoZaFM-eLsW8_F49vQg-R6k9ZeBjGEl8p2YPMbPD2aBOo_7prTkKZHCOtuiOOEkLMgk6fpzkkRW-9Pd6YDvT3mTJC5n272bw0j_fjU-NEYuDs7VnoZsTdi6FO7Q7AeZrghb-2wZ_j3WRmNuJGztp2IJW4epHhfsfwEAAP__JV43og">