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

    <tr>
        <th>Summary</th>
        <td>
            Triples: Environment vs Object type
        </td>
    </tr>

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

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

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

<pre>
    Reproducer:
```c++
#include <cstdio>
#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/Twine.h>
#include <llvm/TargetParser/Triple.h>
#include <llvm/TargetParser/TargetParser.h>

#define props(X) \
 X(hasEnvironment) \
    X(isArch64Bit) \
    X(isArch32Bit) \
 X(isArch16Bit) \
    X(isMacOSX) \
    X(isiOS) \
    X(isTvOS) \
 X(isWatchOS) \
    X(isWatchABI) \
    X(isXROS) \
    X(isDriverKit) \
    X(isOSzOS) \
    X(isOSDarwin) \
    X(isSimulatorEnvironment) \
    X(isMacCatalystEnvironment) \
    X(isTargetMachineMac) \
 X(isOSNetBSD) \
    X(isOSOpenBSD) \
    X(isOSFreeBSD) \
 X(isOSFuchsia) \
    X(isOSDragonFly) \
    X(isOSSolaris) \
 X(isOSIAMCU) \
    X(isOSUnknown) \
    X(isGNUEnvironment) \
 X(isOSHaiku) \
    X(isUEFI) \
    X(isOSWindows) \
 X(isKnownWindowsMSVCEnvironment) \
    X(isWindowsMSVCEnvironment) \
 X(isWindowsArm64EC) \
    X(isWindowsCoreCLREnvironment) \
 X(isWindowsItaniumEnvironment) \
    X(isWindowsCygwinEnvironment) \
 X(isWindowsGNUEnvironment) \
    X(isOSCygMing) \
    X(isOSMSVCRT) \
 X(isOSNaCl) \
    X(isOSLinux) \
    X(isOSKFreeBSD) \
 X(isOSHurd) \
    X(isOSWASI) \
    X(isOSEmscripten) \
 X(isOSGlibc) \
    X(isOSAIX) \
    X(isOSSerenity) \
 X(isOSBinFormatELF) \
    X(isOSBinFormatCOFF) \
    X(isOSBinFormatGOFF) \
    X(isOSBinFormatMachO) \
    X(isOSBinFormatWasm) \
 X(isOSBinFormatXCOFF) \
    X(isOSBinFormatDXContainer) \
    X(isPS4) \
    X(isPS5) \
    X(isPS) \
    X(isAndroid) \
    X(isMusl) \
 X(isOHOSFamily) \
    X(isOpenHOS) \
    X(isOSLiteOS) \
 X(isDXIL) \
    X(isShaderModelOS) \
    X(isVulkanOS) \
 X(isShaderStageEnvironment) \
    X(isSPIR) \
    X(isSPIRV) \
 X(isSPIRVLogical) \
    X(isNVPTX) \
    X(isAMDGCN) \
    X(isAMDGPU) \
    X(isThumb) \
    X(isARM) \
    X(isTargetEHABICompatible) \
 X(isArmT32) \
    X(isArmMClass) \
    X(isAArch64) \
 X(isLoongArch32) \
    X(isLoongArch64) \
    X(isLoongArch) \
 X(isMIPS32) \
    X(isMIPS64) \
    X(isMIPS) \
    X(isPPC) \
 X(isPPC32) \
    X(isPPC64) \
    X(isPPC64ELFv2ABI) \
 X(isPPC32SecurePlt) \
    X(isRISCV32) \
    X(isRISCV64) \
 X(isRISCV) \
    X(isSPARC32) \
    X(isSPARC64) \
    X(isSPARC) \
 X(isSystemZ) \
    X(isX86) \
    X(isVE) \
    X(isWasm) \
 X(isCSKY) \
    X(isArm64e) \
    X(isX32) \
    X(isBPF) \
 X(supportsCOMDAT) \
    X(hasDefaultEmulatedTLS) \
 X(hasDefaultTLSDESC) \
    X(hasDefaultDataSections) \
 X(hasDLLImportExport) \
    X(isLittleEndian)

#define handleProp(P) if (triple.P()) printf(" %s", #P);

const char* rstr(llvm::StringRef r) {
 if (r.size() == 0) return "(empty)";
    char* dst = (char*)malloc(r.size() + 1);
    memcpy(dst, r.begin(), r.size());
 dst[r.size()] = 0;
    return dst;
}

int main(int argc, char** argv) {
 if (argc != 2) {
        printf("Usage: %s <triple>\n", argv[0]);
 return 1;
    }
    std::string normal = llvm::Triple::normalize(argv[1]);
    printf("normalize %s -> %s\n", argv[1], normal.c_str());
    llvm::Triple triple{normal};
 printf("arch: %s\n", rstr(triple.getArchTypeName(triple.getArch())));
 printf("vendor: %s\n", rstr(triple.getVendorTypeName(triple.getVendor())));
    printf("OS: %s\n", rstr(triple.getOSTypeName(triple.getOS())));
    printf("env: %s\n", rstr(triple.getEnvironmentTypeName(triple.getEnvironment())));
 printf("object format: %s\n", rstr(triple.getObjectFormatTypeName(triple.getObjectFormat())));
 props(handleProp);
    printf("\n");
}
```

Hello,

Consider a target triple such as `x86_64-unknown-unknown-elf`.

`-elf` will be considered the object format for the final, normalised `Triple` object, but `hasEnvironment()` will return true, despite there not being a clear environment being set.

`-elf` is not a valid environment, as one can see from `triple.getEnvironmentTypeName(triple.getEnvironment())` returning `unknown`.

Is this a misunderstanding of mine, or is this a bug with the normalisation/parsing of triples? In my opinion, `hasEnvironment()` should return false as `-elf` is not a valid environment, but rather an object format.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykWN9z2j4S_2vEi6aMI4MDDzwYAw1TCExM0ty9fEfYC9ZVljySTEr_-hvZDj-CKNxcJ1Nsffb3rlYrU63ZVgAMUHeIuqMWLU0m1SBnwujyF2utZbofvEChZFomoJAfIi9EgVf_JYgM7Z8XIuIzkfAyBYz8KNEmZRL54wuE812OyCQcrRCZxEYxsX2BTTu7Sbv6YAL-SreiagtmSZUGZV8VK_j_xnHyeuCrWFPYMAG4ULLQiPTeEelj1I2QF-J3RHoZ1WOxY0qKHIQ5ATGucKZDlWRBZ8iugj45B4_IQ3CFbU6TRfzuQtgidi2vdmfr9eJPapLMTV9B4XDqwt5f3DwjxXagfrgtXsR_3FyLeETVBxMuLGZ5yamR6kaI5zSJqKF8r80NyjrPc5pkTMCcJhcxWcTPYIbxyG3qogBxFZwogHPwgJRJphm94r6iWykmfO-GY8mpYtohdRrOo1c306v4JeSHM6bfn1_dMfrkfaLsV-nifB1PnPWwiH8ykcqPSxt_WCMacB6_RTeSc5PyjCxUedAZR38RFEkF0ezlDllTQwUr8_vsi_bbDybukHo11Cehi_bbORNbN2gj8bJy1SiNuJtlxkT52w39uF6gT6VKr6Q2jK8kfZzrRLHCgHAI_M7ZOnHzhVNn41rEMSgQzOwd4oZMTKTKqRnPJm7mA0W0mNwi-X6bxHaIxQ2an1Tnf7P1_Q5TRu-RFIYyYU-hS8pl3HEvd93LziNGpEoyZ3rnpeaXHjwt4gnN2ZWGVIB4utbJZ8yA45wZvU9nzvae0RTUXKbA3RLfSv6LCofEmjM2dAs3dli8nL5cW3-7lGtXZ3LLEurcX89vy5WzesP56Hv0fA1ZOtv0KivztZPlZX797Bo_hcNpJPOCGrbm4Jgb8pVP3LNGPo841doJ1mPKhbiZlGJbTykutgMcOAv1AF_InU-XsVukRdzSLOKs-2V0IX-5jNzil8vILb0CxrPJjpzPPSfyYkhKBUvurLSXaRy9uXVWkCO41bq7OsOXK_ZXkNuDCrqs6b02kP_bOcn1Aue2G7tHQke7i-If_7pSa0EHnDrdbg2Xky_CdVkUUhkdLeajcHXJk1E9gg0tuRlXUyKkq9nXTnGkWc3i0Th2TAtHkhE1NIbEMCm-jjKWaDab5tag8W_7v7PamTEcxiJl1J6JX68QGRUph6WSBSK9pRXANhiRnqlvK0tEepaL9HGhmDCb6p1gRLoaEYJIhBHxLR_yh7XsRAptcJJRhUiIlTYKkV51wfFD5IeHOxauD5dHy9YoVW3N_kCtEiN_hPwR9uyzAlMqgSuNPciL6jy2b5VS6-ynvlQby2mlNUuI9HPKuUwuFJAhfjhYboXkkCfFHpFeqo11TbXXsLW3gDoGduHIf-S01N3hGdYd4dr4g-zGBUtbR-pxVMeLCYNzWmmxj1RtE6vqYH1ol3YXsbJ0GJEHq4acoM2_02y9aroF5IdV1ux1s06uvVB2I9GksVLSHXqoOzp61hj9cHSjNts-aZPWGdVVRrGwswOv3D5me9Voss81QR2jRtvDmbYvZh_oa7u_IX9c192F0bWYqDGhnfxTF91ZkjC-MAs3cXgc1ozWt5r41AxqT4omeCeqm8Ju9skWjD1RVvsCnmkOF8DRmlObTtXsQKRS3aPoraJ0qqoht7Iv0V3E9-haxE49dvq5QweI3T1KTqYlp7azaepWHOX6P5AYvKkm2btcrBjqydft7AnBNf31d5jTZnolJAdL-mdt4PMDVt0SnoBziUhUv0VSaJaCwhSbatpq6hbrMskw1RgF3u9e8E_Q-VbWV-zDL_ANCrx20_QDr1nAH4xzvAacNKIhxSYDfBY7-1Otbpiwg-fn9mIaUquy2dqB17BZinVpLPT1-1MVs0-1TU8xqgTLkoIumAGrSQEW0uA12HZCccKBKgxHQQ2iwVx6xHTFS_GOcpaeclV9QmMpACdUYA2AN0rm1s7_swQDr3HGWoUCr4n6MeJTjU3GNKY4Z7oUKShtqEgtudzgnIkqAlJZ6xvCdbnFH8xkVeQ_A07t8Y_IpKBKN8y1aRr5EzwVON9jWTBRUUV_y4DOZMnTzxxsKNfQVNB9gbQJVtTmClNxXi_tVjrw077fpy0YPDx2idfpdPv9VjbwH_t0QyFIfL-7ftgEQbfX63R6Xb9HO30gpMUGxCNd79Hre4-e_9Bvp72EdgPqE0Kot-n7qONBThlv2xbelmrbYlqXMHjoPAZBt8XpGriuPhkTIuADV2i120YtNbBM39blVqOOx5k2-ijGMMNhsPoMZohPooZ3Gtd7H5t9Aa1S8UFmTGHpEJkgMtkyk5XrdiJzRCbNN9xKWaFkvSUmlSUakUlj6m5A_hsAAP__F0eFqw">