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

    <tr>
        <th>Summary</th>
        <td>
            [clang-tidy] ASTMatchersInternal.cpp getExpansionLocOfMacro() occurs an infinite loop on freecad/src/Mod/Path/App/AreaPyImp.cpp
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-tidy
      </td>
    </tr>

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

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

<pre>
    I realize one simple clang-tidy ast matcher like this:
```
Finder->addMatcher(expr(isExpandedFromMacro("NULL")).bind("E"), this);
```
when I run ```clang-tidy``` on freecad/src/Mod/Path/App/AreaPyImp.cpp it will result in infinite loop in getExpansionLocOfMacro() in ASTMatchersInternal.cpp.

If I use "testchecker" to refer to the matcher implemented above, the clang-tidy command will be like this:
```
freecad $ clang-tidy src/Mod/Path/App/AreaPyImp.cpp -checks=-*,testchecker -p=build/compile_commands.json
```
The branches for both FreeCAD(https://github.com/FreeCAD/FreeCAD.git) and llvm-project are named "main".

I tried to simplify the test code.
AreaPyImp.cpp
```
#include "AreaPy.h"

// The rest of the code is all commented out.
```
AreaPy.h
```
#ifndef PATH_AREAPY_H
#define PATH_AREAPY_H
#include <Mod/Path/App/Area.h>
#endif  // PATH_AREAPY_H

// The rest of the code is all commented out.
```

Area.h
```
#ifndef PATH_AREA_H
#define PATH_AREA_H
#include "AreaParams.h"
#include "Path.h"
namespace Path
{

/** Store libarea algorithm configuration */
struct PathExport CAreaParams {
 PARAM_DECLARE(PARAM_FNAME, AREA_PARAMS_CAREA)
    // CAreaParams();
};

/** Store all Area configurations */
struct PathExport AreaParams: CAreaParams {

    PARAM_DECLARE(PARAM_FNAME, AREA_PARAMS_AREA)

    bool operator==(const AreaParams& other) const {
#define AREA_COMPARE(_param) \
 if(PARAM_FIELD(NAME,_param)!=other.PARAM_FIELD(NAME,_param)) return false;
        PARAM_FOREACH(AREA_COMPARE, AREA_PARAMS_CAREA);
 // PARAM_FOREACH will result in infinite loop !!!
        // PARAM_FOREACH(AREA_COMPARE, AREA_PARAMS_AREA);
        return true;
 }
    bool operator!=(const AreaParams& other) const {
        return !(*this == other);
    }
};

} //namespace Path

// The rest of the code is all commented out.
#endif //PATH_AREA_H

```
As shown above,the macro PARAM_FOREACH will let getExpansionLocOfMacro occur an infinite loop.
```
std::optional<SourceLocation>
getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
                       const ASTContext &Context) {
  auto &SM = Context.getSourceManager();
  const LangOptions &LangOpts = Context.getLangOpts();
  Loc.dump(SM);
  while (Loc.isMacroID()) {
    SrcMgr::ExpansionInfo Expansion =
 SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
    if (Expansion.isMacroArgExpansion())
      // Check macro argument for an expansion of the given macro. For example,
      // `F(G(3))`, where `MacroName` is `G`.
      if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
              MacroName, Expansion.getSpellingLoc(), Context))
        return ArgLoc;
    Loc = Expansion.getExpansionLocStart();
    if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
      return Loc;
  }
  return std::nullopt;
}
```
I try to delete code 
``` 
if (Expansion.isMacroArgExpansion())
      // Check macro argument for an expansion of the given macro. For example,
      // `F(G(3))`, where `MacroName` is `G`.
      if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
              MacroName, Expansion.getSpellingLoc(), Context))
        return ArgLoc;
``` 
and it seems to be able to terminate normally. But it also result in failure in check-clang-unit.
I don't know the exact reason about this. Thanks for your suggestion and help! I'm willing to fix this bug!



</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWE1zozrW_jXy5lQoLPy58IL2x23Xa3en4ryLWaVkOIBuhERJopPcXz8lQTAkdnffmVnMYlwuG5B0zvOc5yAdiRnDc4m4ItMvZLoZsdoWSq_Kv97-j4_OKn1b7UEjE_wvBCURDC8rgZAIJvM7y9M3YMZCyWxSoAbBnxFswQ2JYhJuSBiTWdh-_e2OyxT1HYm2LE2PzShCF_hauT9utq8VkymmO63KI0u0InRBKP32_4cDoZTQJaHL4Mxl2jzfvj9cN17pkkRfrjp-KVDCHnQtoWu5kOgegZKQacSEpYTujE4I3R2Vu75ntiB0F1eV-9XI7t_2ZRUkVQXcwgsXAjSaWljgErjMuOQWQShVuQc5Wk_NcCUPKvmeXcgtXXt8emyjYfbSopZMONNBy8X_7jPYQ20QCKUWjeudPLvwUbAKNGao3YUtsNPDi1WitJgCO6sf2ERqoF-iypLJtKFwxl9r2MYHCJ307fxmsO48bEOizR2hMaHrHhW4q0i0OddcOCOJKisu8KkFaII_jZJXET0WCGfNZFKggUxpOCtbwE4jruMNoYvC2srToTtCdzm3RX0OElUSuus6vV8FObdOFBcSIX6Ud5VWf2JigWkEyUp0xGnJuCSUDvUBqzmmTgP_lvDszcfaEYREpdj2HsTjKh9CIy4TUade66Z_ULhc77lryIDjrp0HlTXKqhSBG2BCeGkb8VVtg6uuOuO3cGQyxQzu48evT_HDNr7_x9PXrjHFjEu80dgxiNY3kiIoSLTt-qNMeQbQ0rpm8z9I-0L-96n_hPg12q1wTLPS9MUbdHEx6TW6_DIVSxB8sJoB8y-f-MeExnCySrvX9cw0MmAiV5rbooREyYzntWaWKwm-864Za6yuE-ttb18rpS2sLxihcwT38UN8fNps14f4YUvoornffYuPWzeBeMb-2elp7W7cvNuMhE7AnuVmmrvMzPPN5foqJyeiGz6kYn7Bpecwiq8zu6D8GxQHDC8WzkoJUBVqZpUm0cZ96SJR0gyg0Bko61e5JTSNFzRdInl36-_H-wbMU-XGuhFkum498uyCcr89OF8t2K43oWMSbby34Fc9l6DR1lpCxoTBTg9oP-3w7w_beP2V0MUQ4I0U6Ix073DPyM-XSAe9-Q5gXDP0CzSfwLSflq7VdY-tS8UbgvpY_k1BP_jyjBaExm41hSZFurEDgB2OK-_GfNOG4erk8G_Nie-TbjP-82x2dcEwYAr1Irt6oqk3Eq2u6S3Q3qh9QCVJrYF9yITr07WxqVu-o1hVbiZggkTrk6p1ggeV-MmhW0luVlonq7nMHzAD_-QbK301NDQDB5UQuh7K-eHTZsTpca2kxVcLhM7aS__KXrKB1Va51tPRqQ9tpyBH23g9MslyXwAPE6LxcGAy_169z3yz9tZ8NPX-_JOVg0qCtC4rx_04bHopuHDrz8L14cYHZL9pLQw5AJx0csx1E_8utHuZKejufHI3A05Hz--gkq20-s07d092XKB34SPs6_i-VJ_QA_jEXHQ93nHGOv84qr_8XBYgV1O2mcl0Xrv098Uhk4Ad8PZVyfkPlE3nAHZKA74yVzt_yIXWNJmFO0IXfxC6iFr_s9Al00uBGl3zJcVmoXsFySz8g8zCoG-s4fdbqQ2xzg8q8dLf3kpcSdpBql9C6RSqUAgucy_Hot1EXdL4Q0y7Oa0BMtDpHdjAfB_iyTJtbwrMzaN6RhnbBolL1TVckno95NBlTx9di20IrDe3t-1dqGUthKrsoCK5Nu24iv7N1fMpCrTthPqhZ3v_v2T970_Wj5q5LR63YBBL41Q-I7CzQL-JRl1yySyCVLpkQrwF8KW2rjsTRvXqmIxxUWt0l34Xe9dsiWvJ35fZPaRO_LmFZ6levIL4yhILGplRfiGtrd9xB_BYMPnc7GHfVK3B1HmOxq9MDm2BoiJ0DHtC56VfYbnMHd6Mv3oLcK7zrorq_47SVZQuoyUb4Wo8j8LJNFzSxahYpdE8jcIznsd0mszHNAwn42kSTbN0Go7DFEd8RUM6GY_DcbiYLCaLIJqfp5NwOV9OojSj2YxMQiwZF4HbLgdK5yNuTI2r8XgypeORYGcUxp8vUdo7cqGUTDcjvfKb7HOdGzIJBTfWXOxYboU_meoNm25uHZb8_JDFlxvmU73xrxz4jGotVj85U3D427_30wNCdz4ohtBdG5cfK_rPAAAA__-k-sh1">