Skip to content

Commit f74e82f

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:dd0b3c2fa627 into amd-gfx:dffa6f98e667
Local branch amd-gfx dffa6f9 Merged main:c0722478d5c1 into amd-gfx:94e1716d2b22 Remote branch main dd0b3c2 [clang][analyzer] Support `fprintf` in the SecuritySyntaxChecker (llvm#73247)
2 parents dffa6f9 + dd0b3c2 commit f74e82f

File tree

11 files changed

+248
-46
lines changed

11 files changed

+248
-46
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,10 @@ def warn_unsupported_target_attribute
31773177
def err_attribute_unsupported
31783178
: Error<"%0 attribute is not supported on targets missing %1;"
31793179
" specify an appropriate -march= or -mcpu=">;
3180+
def err_duplicate_target_attribute
3181+
: Error<"%select{unsupported|duplicate|unknown}0%select{| CPU|"
3182+
" tune CPU}1 '%2' in the '%select{target|target_clones|target_version}3' "
3183+
"attribute string; ">;
31803184
// The err_*_attribute_argument_not_int are separate because they're used by
31813185
// VerifyIntegerConstantExpression.
31823186
def err_aligned_attribute_argument_not_int : Error<

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,47 @@ ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
235235
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
236236
}
237237

238+
static std::vector<std::string>
239+
collectNonISAExtFeature(const std::vector<std::string> &FeaturesNeedOverride,
240+
int XLen) {
241+
auto ParseResult =
242+
llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesNeedOverride);
243+
244+
if (!ParseResult) {
245+
consumeError(ParseResult.takeError());
246+
return std::vector<std::string>();
247+
}
248+
249+
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
250+
251+
std::vector<std::string> NonISAExtFeatureVec;
252+
253+
llvm::copy_if(FeaturesNeedOverride, std::back_inserter(NonISAExtFeatureVec),
254+
[&](const std::string &Feat) {
255+
return !llvm::is_contained(ImpliedFeatures, Feat);
256+
});
257+
258+
return NonISAExtFeatureVec;
259+
}
260+
261+
static std::vector<std::string>
262+
resolveTargetAttrOverride(const std::vector<std::string> &FeaturesVec,
263+
int XLen) {
264+
auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
265+
if (I == FeaturesVec.end())
266+
return FeaturesVec;
267+
268+
const std::vector<std::string> FeaturesNeedOverride(FeaturesVec.begin(), I);
269+
std::vector<std::string> NonISAExtFeature =
270+
collectNonISAExtFeature(FeaturesNeedOverride, XLen);
271+
272+
auto ResolvedFeature = std::vector(++I, FeaturesVec.end());
273+
ResolvedFeature.insert(ResolvedFeature.end(), NonISAExtFeature.begin(),
274+
NonISAExtFeature.end());
275+
276+
return ResolvedFeature;
277+
}
278+
238279
bool RISCVTargetInfo::initFeatureMap(
239280
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
240281
const std::vector<std::string> &FeaturesVec) const {
@@ -248,7 +289,10 @@ bool RISCVTargetInfo::initFeatureMap(
248289
Features["32bit"] = true;
249290
}
250291

251-
auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
292+
std::vector<std::string> NewFeaturesVec =
293+
resolveTargetAttrOverride(FeaturesVec, XLen);
294+
295+
auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, NewFeaturesVec);
252296
if (!ParseResult) {
253297
std::string Buffer;
254298
llvm::raw_string_ostream OutputErrMsg(Buffer);
@@ -262,7 +306,7 @@ bool RISCVTargetInfo::initFeatureMap(
262306
// RISCVISAInfo makes implications for ISA features
263307
std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
264308
// Add non-ISA features like `relax` and `save-restore` back
265-
for (const std::string &Feature : FeaturesVec)
309+
for (const std::string &Feature : NewFeaturesVec)
266310
if (!llvm::is_contained(ImpliedFeatures, Feature))
267311
ImpliedFeatures.push_back(Feature);
268312

@@ -359,3 +403,82 @@ void RISCVTargetInfo::fillValidTuneCPUList(
359403
bool Is64Bit = getTriple().isArch64Bit();
360404
llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
361405
}
406+
407+
static void handleFullArchString(StringRef FullArchStr,
408+
std::vector<std::string> &Features) {
409+
Features.push_back("__RISCV_TargetAttrNeedOverride");
410+
auto RII = llvm::RISCVISAInfo::parseArchString(
411+
FullArchStr, /* EnableExperimentalExtension */ true);
412+
if (!RII) {
413+
consumeError(RII.takeError());
414+
// Forward the invalid FullArchStr.
415+
Features.push_back("+" + FullArchStr.str());
416+
} else {
417+
std::vector<std::string> FeatStrings = (*RII)->toFeatureVector();
418+
for (auto FeatString : FeatStrings)
419+
Features.push_back(FeatString);
420+
}
421+
}
422+
423+
ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
424+
ParsedTargetAttr Ret;
425+
if (Features == "default")
426+
return Ret;
427+
SmallVector<StringRef, 1> AttrFeatures;
428+
Features.split(AttrFeatures, ";");
429+
bool FoundArch = false;
430+
431+
for (auto &Feature : AttrFeatures) {
432+
Feature = Feature.trim();
433+
StringRef AttrString = Feature.split("=").second.trim();
434+
435+
if (Feature.startswith("arch=")) {
436+
// Override last features
437+
Ret.Features.clear();
438+
if (FoundArch)
439+
Ret.Duplicate = "arch=";
440+
FoundArch = true;
441+
442+
if (AttrString.startswith("+")) {
443+
// EXTENSION like arch=+v,+zbb
444+
SmallVector<StringRef, 1> Exts;
445+
AttrString.split(Exts, ",");
446+
for (auto Ext : Exts) {
447+
if (Ext.empty())
448+
continue;
449+
450+
StringRef ExtName = Ext.substr(1);
451+
std::string TargetFeature =
452+
llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
453+
if (!TargetFeature.empty())
454+
Ret.Features.push_back(Ext.front() + TargetFeature);
455+
else
456+
Ret.Features.push_back(Ext.str());
457+
}
458+
} else {
459+
// full-arch-string like arch=rv64gcv
460+
handleFullArchString(AttrString, Ret.Features);
461+
}
462+
} else if (Feature.startswith("cpu=")) {
463+
if (!Ret.CPU.empty())
464+
Ret.Duplicate = "cpu=";
465+
466+
Ret.CPU = AttrString;
467+
468+
if (!FoundArch) {
469+
// Update Features with CPU's features
470+
StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
471+
if (MarchFromCPU != "") {
472+
Ret.Features.clear();
473+
handleFullArchString(MarchFromCPU, Ret.Features);
474+
}
475+
}
476+
} else if (Feature.startswith("tune=")) {
477+
if (!Ret.Tune.empty())
478+
Ret.Duplicate = "tune=";
479+
480+
Ret.Tune = AttrString;
481+
}
482+
}
483+
return Ret;
484+
}

clang/lib/Basic/Targets/RISCV.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class RISCVTargetInfo : public TargetInfo {
117117
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
118118
bool isValidTuneCPUName(StringRef Name) const override;
119119
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
120+
bool supportsTargetAttributeTune() const override { return true; }
121+
ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
120122
};
121123
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
122124
public:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3451,6 +3451,11 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
34513451
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
34523452
<< Unknown << Tune << ParsedAttrs.Tune << Target;
34533453

3454+
if (Context.getTargetInfo().getTriple().isRISCV() &&
3455+
ParsedAttrs.Duplicate != "")
3456+
return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
3457+
<< Duplicate << None << ParsedAttrs.Duplicate << Target;
3458+
34543459
if (ParsedAttrs.Duplicate != "")
34553460
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
34563461
<< Duplicate << None << ParsedAttrs.Duplicate << Target;

clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -144,38 +144,39 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
144144
Name = Name.substr(10);
145145

146146
// Set the evaluation function by switching on the callee name.
147-
FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
148-
.Case("bcmp", &WalkAST::checkCall_bcmp)
149-
.Case("bcopy", &WalkAST::checkCall_bcopy)
150-
.Case("bzero", &WalkAST::checkCall_bzero)
151-
.Case("gets", &WalkAST::checkCall_gets)
152-
.Case("getpw", &WalkAST::checkCall_getpw)
153-
.Case("mktemp", &WalkAST::checkCall_mktemp)
154-
.Case("mkstemp", &WalkAST::checkCall_mkstemp)
155-
.Case("mkdtemp", &WalkAST::checkCall_mkstemp)
156-
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
157-
.Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
158-
.Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
159-
.Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
160-
"vscanf", "vwscanf", "vfscanf", "vfwscanf",
161-
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
162-
.Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
163-
"snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
164-
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
165-
.Cases("strncpy", "strncat", "memset",
166-
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
167-
.Case("drand48", &WalkAST::checkCall_rand)
168-
.Case("erand48", &WalkAST::checkCall_rand)
169-
.Case("jrand48", &WalkAST::checkCall_rand)
170-
.Case("lrand48", &WalkAST::checkCall_rand)
171-
.Case("mrand48", &WalkAST::checkCall_rand)
172-
.Case("nrand48", &WalkAST::checkCall_rand)
173-
.Case("lcong48", &WalkAST::checkCall_rand)
174-
.Case("rand", &WalkAST::checkCall_rand)
175-
.Case("rand_r", &WalkAST::checkCall_rand)
176-
.Case("random", &WalkAST::checkCall_random)
177-
.Case("vfork", &WalkAST::checkCall_vfork)
178-
.Default(nullptr);
147+
FnCheck evalFunction =
148+
llvm::StringSwitch<FnCheck>(Name)
149+
.Case("bcmp", &WalkAST::checkCall_bcmp)
150+
.Case("bcopy", &WalkAST::checkCall_bcopy)
151+
.Case("bzero", &WalkAST::checkCall_bzero)
152+
.Case("gets", &WalkAST::checkCall_gets)
153+
.Case("getpw", &WalkAST::checkCall_getpw)
154+
.Case("mktemp", &WalkAST::checkCall_mktemp)
155+
.Case("mkstemp", &WalkAST::checkCall_mkstemp)
156+
.Case("mkdtemp", &WalkAST::checkCall_mkstemp)
157+
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
158+
.Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
159+
.Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
160+
.Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
161+
"vscanf", "vwscanf", "vfscanf", "vfwscanf",
162+
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
163+
.Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
164+
"snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
165+
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
166+
.Cases("strncpy", "strncat", "memset", "fprintf",
167+
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
168+
.Case("drand48", &WalkAST::checkCall_rand)
169+
.Case("erand48", &WalkAST::checkCall_rand)
170+
.Case("jrand48", &WalkAST::checkCall_rand)
171+
.Case("lrand48", &WalkAST::checkCall_rand)
172+
.Case("mrand48", &WalkAST::checkCall_rand)
173+
.Case("nrand48", &WalkAST::checkCall_rand)
174+
.Case("lcong48", &WalkAST::checkCall_rand)
175+
.Case("rand", &WalkAST::checkCall_rand)
176+
.Case("rand_r", &WalkAST::checkCall_rand)
177+
.Case("random", &WalkAST::checkCall_random)
178+
.Case("vfork", &WalkAST::checkCall_vfork)
179+
.Default(nullptr);
179180

180181
// If the callee isn't defined, it is not of security concern.
181182
// Check and evaluate the call.
@@ -737,10 +738,10 @@ void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
737738
// Check: Any use of 'sprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
738739
// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
739740
// 'swscanf', 'vsscanf', 'vswscanf', 'swprintf', 'snprintf', 'vswprintf',
740-
// 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset'
741-
// is deprecated since C11.
741+
// 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset',
742+
// 'fprintf' is deprecated since C11.
742743
//
743-
// Use of 'sprintf', 'vsprintf', 'scanf', 'wscanf','fscanf',
744+
// Use of 'sprintf', 'fprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
744745
// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
745746
// 'swscanf', 'vsscanf', 'vswscanf' without buffer limitations
746747
// is insecure.
@@ -768,8 +769,9 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
768769
int ArgIndex =
769770
llvm::StringSwitch<int>(Name)
770771
.Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)
771-
.Cases("sprintf", "vsprintf", "fscanf", "fwscanf", "vfscanf",
772-
"vfwscanf", "sscanf", "swscanf", "vsscanf", "vswscanf", 1)
772+
.Cases("fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf",
773+
"swscanf", "vsscanf", "vswscanf", 1)
774+
.Cases("sprintf", "vsprintf", "fprintf", 1)
773775
.Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
774776
"memmove", "memset", "strncpy", "strncat", DEPR_ONLY)
775777
.Default(UNKNOWN_CALL);

clang/test/Analysis/security-syntax-checks.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,24 @@
55
// RUN: %clang_analyze_cc1 %s -verify -std=gnu99 \
66
// RUN: -analyzer-checker=security.insecureAPI
77

8+
#include "Inputs/system-header-simulator.h"
9+
10+
extern FILE *fp;
11+
extern char buf[128];
12+
813
void builtin_function_call_crash_fixes(char *c) {
914
__builtin_strncpy(c, "", 6);
1015
__builtin_memset(c, '\0', (0));
1116
__builtin_memcpy(c, c, 0);
17+
__builtin_sprintf(buf, "%s", c);
18+
__builtin_fprintf(fp, "%s", c);
1219

1320
#if __STDC_VERSION__ > 199901
14-
// expected-warning@-5{{Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
15-
// expected-warning@-5{{Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard.}}
16-
// expected-warning@-5{{Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
21+
// expected-warning@-7{{Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
22+
// expected-warning@-7{{Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard.}}
23+
// expected-warning@-7{{Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
24+
// expected-warning@-7{{Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard.}}
25+
// expected-warning@-7{{Call to function 'fprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard.}}
1726
#else
1827
// expected-no-diagnostics
1928
#endif
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// REQUIRES: riscv-registered-target
2+
// RUN: not %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m -target-feature +a \
3+
// RUN: -emit-llvm %s 2>&1 | FileCheck %s
4+
5+
// CHECK: error: duplicate 'arch=' in the 'target' attribute string;
6+
__attribute__((target("arch=rv64gc;arch=rv64gc_zbb"))) void testMultiArchSelectLast() {}
7+
// CHECK: error: duplicate 'cpu=' in the 'target' attribute string;
8+
__attribute__((target("cpu=sifive-u74;cpu=sifive-u54"))) void testMultiCpuSelectLast() {}
9+
// CHECK: error: duplicate 'tune=' in the 'target' attribute string;
10+
__attribute__((target("tune=sifive-u74;tune=sifive-u54"))) void testMultiTuneSelectLast() {}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// REQUIRES: riscv-registered-target
2+
// RUN: %clang_cc1 -triple riscv64 -target-feature +zifencei -target-feature +m \
3+
// RUN: -target-feature +a -target-feature +save-restore \
4+
// RUN: -emit-llvm %s -o - | FileCheck %s
5+
6+
// CHECK-LABEL: define dso_local void @testDefault
7+
// CHECK-SAME: () #0 {
8+
void testDefault() {}
9+
// CHECK-LABEL: define dso_local void @testMultiAttrStr
10+
// CHECK-SAME: () #1 {
11+
__attribute__((target("cpu=rocket-rv64;tune=generic-rv64;arch=+v"))) void
12+
testMultiAttrStr() {}
13+
// CHECK-LABEL: define dso_local void @testSingleExtension
14+
// CHECK-SAME: () #2 {
15+
__attribute__((target("arch=+zbb"))) void testSingleExtension() {}
16+
// CHECK-LABEL: define dso_local void @testMultiExtension
17+
// CHECK-SAME: () #3 {
18+
__attribute__((target("arch=+zbb,+v,+zicond"))) void testMultiExtension() {}
19+
// CHECK-LABEL: define dso_local void @testFullArch
20+
// CHECK-SAME: () #4 {
21+
__attribute__((target("arch=rv64gc_zbb"))) void testFullArch() {}
22+
// CHECK-LABEL: define dso_local void @testFullArchButSmallThanCmdArch
23+
// CHECK-SAME: () #5 {
24+
__attribute__((target("arch=rv64im"))) void testFullArchButSmallThanCmdArch() {}
25+
// CHECK-LABEL: define dso_local void @testAttrArchAndAttrCpu
26+
// CHECK-SAME: () #6 {
27+
__attribute__((target("cpu=sifive-u54;arch=+zbb"))) void
28+
testAttrArchAndAttrCpu() {}
29+
// CHECK-LABEL: define dso_local void @testAttrFullArchAndAttrCpu
30+
// CHECK-SAME: () #7 {
31+
__attribute__((target("cpu=sifive-u54;arch=rv64im"))) void
32+
testAttrFullArchAndAttrCpu() {}
33+
// CHECK-LABEL: define dso_local void @testAttrCpuOnly
34+
// CHECK-SAME: () #8 {
35+
__attribute__((target("cpu=sifive-u54"))) void testAttrCpuOnly() {}
36+
37+
//.
38+
// CHECK: attributes #0 = { {{.*}}"target-features"="+64bit,+a,+m,+save-restore,+zifencei" }
39+
// CHECK: attributes #1 = { {{.*}}"target-cpu"="rocket-rv64" "target-features"="+64bit,+a,+d,+f,+m,+save-restore,+v,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" "tune-cpu"="generic-rv64" }
40+
// CHECK: attributes #2 = { {{.*}}"target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei" }
41+
// CHECK: attributes #3 = { {{.*}}"target-features"="+64bit,+a,+d,+experimental-zicond,+f,+m,+save-restore,+v,+zbb,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b" }
42+
// CHECK: attributes #4 = { {{.*}}"target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zbb,+zicsr,+zifencei" }
43+
// CHECK: attributes #5 = { {{.*}}"target-features"="+64bit,+m,+save-restore" }
44+
// CHECK: attributes #6 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei" }
45+
// CHECK: attributes #7 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+m,+save-restore" }
46+
// CHECK: attributes #8 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zicsr,+zifencei" }

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/* Indicate that this is LLVM compiled from the amd-gfx branch. */
1818
#define LLVM_HAVE_BRANCH_AMD_GFX
19-
#define LLVM_MAIN_REVISION 481630
19+
#define LLVM_MAIN_REVISION 481634
2020

2121
/* Define if LLVM_ENABLE_DUMP is enabled */
2222
#cmakedefine LLVM_ENABLE_DUMP

llvm/lib/Support/Unix/Path.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ const file_t kInvalidFile = -1;
129129
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
130130
defined(__FreeBSD_kernel__) || defined(__linux__) || defined(__CYGWIN__) || \
131131
defined(__DragonFly__) || defined(_AIX) || defined(__GNU__) || \
132-
(defined(__sun__) && defined(__svr4__))
132+
(defined(__sun__) && defined(__svr4__) || defined(__HAIKU__))
133133
static int test_dir(char ret[PATH_MAX], const char *dir, const char *bin) {
134134
struct stat sb;
135135
char fullpath[PATH_MAX];
@@ -283,7 +283,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
283283
// Fall back to the classical detection.
284284
if (getprogpath(exe_path, argv0))
285285
return exe_path;
286-
#elif defined(__OpenBSD__)
286+
#elif defined(__OpenBSD__) || defined(__HAIKU__)
287287
char exe_path[PATH_MAX];
288288
// argv[0] only
289289
if (getprogpath(exe_path, argv0) != NULL)

0 commit comments

Comments
 (0)