mirror of https://github.com/tinygo-org/tinygo.git
Browse Source
This implementation is still very limited but provides a base to build upon. Limitations: * CGO_CFLAGS etc is not taken into account. * These CFLAGS are not used in C files compiled with the package. * Other flags (CPPFLAGS, LDFAGS, ...) are not yet implemented.pull/754/head
Ayke van Laethem
5 years ago
committed by
Ron Evans
9 changed files with 738 additions and 9 deletions
@ -0,0 +1,301 @@ |
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
|||
// Use of this source code is governed by a BSD-style
|
|||
// license that can be found in the LICENSE file.
|
|||
|
|||
// This file has been copied from the Go 1.13 release tree.
|
|||
|
|||
// Checking of compiler and linker flags.
|
|||
// We must avoid flags like -fplugin=, which can allow
|
|||
// arbitrary code execution during the build.
|
|||
// Do not make changes here without carefully
|
|||
// considering the implications.
|
|||
// (That's why the code is isolated in a file named security.go.)
|
|||
//
|
|||
// Note that -Wl,foo means split foo on commas and pass to
|
|||
// the linker, so that -Wl,-foo,bar means pass -foo bar to
|
|||
// the linker. Similarly -Wa,foo for the assembler and so on.
|
|||
// If any of these are permitted, the wildcard portion must
|
|||
// disallow commas.
|
|||
//
|
|||
// Note also that GNU binutils accept any argument @foo
|
|||
// as meaning "read more flags from the file foo", so we must
|
|||
// guard against any command-line argument beginning with @,
|
|||
// even things like "-I @foo".
|
|||
// We use safeArg (which is even more conservative)
|
|||
// to reject these.
|
|||
//
|
|||
// Even worse, gcc -I@foo (one arg) turns into cc1 -I @foo (two args),
|
|||
// so although gcc doesn't expand the @foo, cc1 will.
|
|||
// So out of paranoia, we reject @ at the beginning of every
|
|||
// flag argument that might be split into its own argument.
|
|||
|
|||
package cgo |
|||
|
|||
import ( |
|||
"fmt" |
|||
"os" |
|||
"regexp" |
|||
"strings" |
|||
"unicode/utf8" |
|||
) |
|||
|
|||
var re = regexp.MustCompile |
|||
|
|||
var validCompilerFlags = []*regexp.Regexp{ |
|||
re(`-D([A-Za-z_].*)`), |
|||
re(`-F([^@\-].*)`), |
|||
re(`-I([^@\-].*)`), |
|||
re(`-O`), |
|||
re(`-O([^@\-].*)`), |
|||
re(`-W`), |
|||
re(`-W([^@,]+)`), // -Wall but not -Wa,-foo.
|
|||
re(`-Wa,-mbig-obj`), |
|||
re(`-Wp,-D([A-Za-z_].*)`), |
|||
re(`-ansi`), |
|||
re(`-f(no-)?asynchronous-unwind-tables`), |
|||
re(`-f(no-)?blocks`), |
|||
re(`-f(no-)builtin-[a-zA-Z0-9_]*`), |
|||
re(`-f(no-)?common`), |
|||
re(`-f(no-)?constant-cfstrings`), |
|||
re(`-fdiagnostics-show-note-include-stack`), |
|||
re(`-f(no-)?eliminate-unused-debug-types`), |
|||
re(`-f(no-)?exceptions`), |
|||
re(`-f(no-)?fast-math`), |
|||
re(`-f(no-)?inline-functions`), |
|||
re(`-finput-charset=([^@\-].*)`), |
|||
re(`-f(no-)?fat-lto-objects`), |
|||
re(`-f(no-)?keep-inline-dllexport`), |
|||
re(`-f(no-)?lto`), |
|||
re(`-fmacro-backtrace-limit=(.+)`), |
|||
re(`-fmessage-length=(.+)`), |
|||
re(`-f(no-)?modules`), |
|||
re(`-f(no-)?objc-arc`), |
|||
re(`-f(no-)?objc-nonfragile-abi`), |
|||
re(`-f(no-)?objc-legacy-dispatch`), |
|||
re(`-f(no-)?omit-frame-pointer`), |
|||
re(`-f(no-)?openmp(-simd)?`), |
|||
re(`-f(no-)?permissive`), |
|||
re(`-f(no-)?(pic|PIC|pie|PIE)`), |
|||
re(`-f(no-)?plt`), |
|||
re(`-f(no-)?rtti`), |
|||
re(`-f(no-)?split-stack`), |
|||
re(`-f(no-)?stack-(.+)`), |
|||
re(`-f(no-)?strict-aliasing`), |
|||
re(`-f(un)signed-char`), |
|||
re(`-f(no-)?use-linker-plugin`), // safe if -B is not used; we don't permit -B
|
|||
re(`-f(no-)?visibility-inlines-hidden`), |
|||
re(`-fsanitize=(.+)`), |
|||
re(`-ftemplate-depth-(.+)`), |
|||
re(`-fvisibility=(.+)`), |
|||
re(`-g([^@\-].*)?`), |
|||
re(`-m32`), |
|||
re(`-m64`), |
|||
re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`), |
|||
re(`-m(no-)?v?aes`), |
|||
re(`-marm`), |
|||
re(`-m(no-)?avx[0-9a-z]*`), |
|||
re(`-mfloat-abi=([^@\-].*)`), |
|||
re(`-mfpmath=[0-9a-z,+]*`), |
|||
re(`-m(no-)?avx[0-9a-z.]*`), |
|||
re(`-m(no-)?ms-bitfields`), |
|||
re(`-m(no-)?stack-(.+)`), |
|||
re(`-mmacosx-(.+)`), |
|||
re(`-mios-simulator-version-min=(.+)`), |
|||
re(`-miphoneos-version-min=(.+)`), |
|||
re(`-mtvos-simulator-version-min=(.+)`), |
|||
re(`-mtvos-version-min=(.+)`), |
|||
re(`-mwatchos-simulator-version-min=(.+)`), |
|||
re(`-mwatchos-version-min=(.+)`), |
|||
re(`-mnop-fun-dllimport`), |
|||
re(`-m(no-)?sse[0-9.]*`), |
|||
re(`-m(no-)?ssse3`), |
|||
re(`-mthumb(-interwork)?`), |
|||
re(`-mthreads`), |
|||
re(`-mwindows`), |
|||
re(`--param=ssp-buffer-size=[0-9]*`), |
|||
re(`-pedantic(-errors)?`), |
|||
re(`-pipe`), |
|||
re(`-pthread`), |
|||
re(`-?-std=([^@\-].*)`), |
|||
re(`-?-stdlib=([^@\-].*)`), |
|||
re(`--sysroot=([^@\-].*)`), |
|||
re(`-w`), |
|||
re(`-x([^@\-].*)`), |
|||
re(`-v`), |
|||
} |
|||
|
|||
var validCompilerFlagsWithNextArg = []string{ |
|||
"-arch", |
|||
"-D", |
|||
"-I", |
|||
"-framework", |
|||
"-isysroot", |
|||
"-isystem", |
|||
"--sysroot", |
|||
"-target", |
|||
"-x", |
|||
} |
|||
|
|||
var validLinkerFlags = []*regexp.Regexp{ |
|||
re(`-F([^@\-].*)`), |
|||
re(`-l([^@\-].*)`), |
|||
re(`-L([^@\-].*)`), |
|||
re(`-O`), |
|||
re(`-O([^@\-].*)`), |
|||
re(`-f(no-)?(pic|PIC|pie|PIE)`), |
|||
re(`-f(no-)?openmp(-simd)?`), |
|||
re(`-fsanitize=([^@\-].*)`), |
|||
re(`-flat_namespace`), |
|||
re(`-g([^@\-].*)?`), |
|||
re(`-headerpad_max_install_names`), |
|||
re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`), |
|||
re(`-mfloat-abi=([^@\-].*)`), |
|||
re(`-mmacosx-(.+)`), |
|||
re(`-mios-simulator-version-min=(.+)`), |
|||
re(`-miphoneos-version-min=(.+)`), |
|||
re(`-mthreads`), |
|||
re(`-mwindows`), |
|||
re(`-(pic|PIC|pie|PIE)`), |
|||
re(`-pthread`), |
|||
re(`-rdynamic`), |
|||
re(`-shared`), |
|||
re(`-?-static([-a-z0-9+]*)`), |
|||
re(`-?-stdlib=([^@\-].*)`), |
|||
re(`-v`), |
|||
|
|||
// Note that any wildcards in -Wl need to exclude comma,
|
|||
// since -Wl splits its argument at commas and passes
|
|||
// them all to the linker uninterpreted. Allowing comma
|
|||
// in a wildcard would allow tunnelling arbitrary additional
|
|||
// linker arguments through one of these.
|
|||
re(`-Wl,--(no-)?allow-multiple-definition`), |
|||
re(`-Wl,--(no-)?allow-shlib-undefined`), |
|||
re(`-Wl,--(no-)?as-needed`), |
|||
re(`-Wl,-Bdynamic`), |
|||
re(`-Wl,-berok`), |
|||
re(`-Wl,-Bstatic`), |
|||
re(`-WL,-O([^@,\-][^,]*)?`), |
|||
re(`-Wl,-d[ny]`), |
|||
re(`-Wl,--disable-new-dtags`), |
|||
re(`-Wl,-e[=,][a-zA-Z0-9]*`), |
|||
re(`-Wl,--enable-new-dtags`), |
|||
re(`-Wl,--end-group`), |
|||
re(`-Wl,--(no-)?export-dynamic`), |
|||
re(`-Wl,-framework,[^,@\-][^,]+`), |
|||
re(`-Wl,-headerpad_max_install_names`), |
|||
re(`-Wl,--no-undefined`), |
|||
re(`-Wl,-R([^@\-][^,@]*$)`), |
|||
re(`-Wl,--just-symbols[=,]([^,@\-][^,@]+)`), |
|||
re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`), |
|||
re(`-Wl,-s`), |
|||
re(`-Wl,-search_paths_first`), |
|||
re(`-Wl,-sectcreate,([^,@\-][^,]+),([^,@\-][^,]+),([^,@\-][^,]+)`), |
|||
re(`-Wl,--start-group`), |
|||
re(`-Wl,-?-static`), |
|||
re(`-Wl,-?-subsystem,(native|windows|console|posix|xbox)`), |
|||
re(`-Wl,-syslibroot[=,]([^,@\-][^,]+)`), |
|||
re(`-Wl,-undefined[=,]([^,@\-][^,]+)`), |
|||
re(`-Wl,-?-unresolved-symbols=[^,]+`), |
|||
re(`-Wl,--(no-)?warn-([^,]+)`), |
|||
re(`-Wl,-z,(no)?execstack`), |
|||
re(`-Wl,-z,relro`), |
|||
|
|||
re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)
|
|||
re(`\./.*\.(a|o|obj|dll|dylib|so)`), |
|||
} |
|||
|
|||
var validLinkerFlagsWithNextArg = []string{ |
|||
"-arch", |
|||
"-F", |
|||
"-l", |
|||
"-L", |
|||
"-framework", |
|||
"-isysroot", |
|||
"--sysroot", |
|||
"-target", |
|||
"-Wl,-framework", |
|||
"-Wl,-rpath", |
|||
"-Wl,-R", |
|||
"-Wl,--just-symbols", |
|||
"-Wl,-undefined", |
|||
} |
|||
|
|||
func checkCompilerFlags(name string, list []string) error { |
|||
return checkFlags(name, list, validCompilerFlags, validCompilerFlagsWithNextArg) |
|||
} |
|||
|
|||
func checkLinkerFlags(name string, list []string) error { |
|||
return checkFlags(name, list, validLinkerFlags, validLinkerFlagsWithNextArg) |
|||
} |
|||
|
|||
func checkFlags(name string, list []string, valid []*regexp.Regexp, validNext []string) error { |
|||
// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
|
|||
var ( |
|||
allow *regexp.Regexp |
|||
disallow *regexp.Regexp |
|||
) |
|||
if env := os.Getenv("CGO_" + name + "_ALLOW"); env != "" { |
|||
r, err := regexp.Compile(env) |
|||
if err != nil { |
|||
return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err) |
|||
} |
|||
allow = r |
|||
} |
|||
if env := os.Getenv("CGO_" + name + "_DISALLOW"); env != "" { |
|||
r, err := regexp.Compile(env) |
|||
if err != nil { |
|||
return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err) |
|||
} |
|||
disallow = r |
|||
} |
|||
|
|||
Args: |
|||
for i := 0; i < len(list); i++ { |
|||
arg := list[i] |
|||
if disallow != nil && disallow.FindString(arg) == arg { |
|||
goto Bad |
|||
} |
|||
if allow != nil && allow.FindString(arg) == arg { |
|||
continue Args |
|||
} |
|||
for _, re := range valid { |
|||
if re.FindString(arg) == arg { // must be complete match
|
|||
continue Args |
|||
} |
|||
} |
|||
for _, x := range validNext { |
|||
if arg == x { |
|||
if i+1 < len(list) && safeArg(list[i+1]) { |
|||
i++ |
|||
continue Args |
|||
} |
|||
|
|||
// Permit -Wl,-framework -Wl,name.
|
|||
if i+1 < len(list) && |
|||
strings.HasPrefix(arg, "-Wl,") && |
|||
strings.HasPrefix(list[i+1], "-Wl,") && |
|||
safeArg(list[i+1][4:]) && |
|||
!strings.Contains(list[i+1][4:], ",") { |
|||
i++ |
|||
continue Args |
|||
} |
|||
|
|||
if i+1 < len(list) { |
|||
return fmt.Errorf("invalid flag: %s %s (see https://golang.org/s/invalidflag)", arg, list[i+1]) |
|||
} |
|||
return fmt.Errorf("invalid flag: %s without argument (see https://golang.org/s/invalidflag)", arg) |
|||
} |
|||
} |
|||
Bad: |
|||
return fmt.Errorf("invalid flag: %s", arg) |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func safeArg(name string) bool { |
|||
if name == "" { |
|||
return false |
|||
} |
|||
c := name[0] |
|||
return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf |
|||
} |
@ -0,0 +1,260 @@ |
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
|||
// Use of this source code is governed by a BSD-style
|
|||
// license that can be found in the LICENSE file.
|
|||
|
|||
// This file has been copied from the Go 1.13 release tree.
|
|||
|
|||
package cgo |
|||
|
|||
import ( |
|||
"os" |
|||
"testing" |
|||
) |
|||
|
|||
var goodCompilerFlags = [][]string{ |
|||
{"-DFOO"}, |
|||
{"-Dfoo=bar"}, |
|||
{"-F/Qt"}, |
|||
{"-I/"}, |
|||
{"-I/etc/passwd"}, |
|||
{"-I."}, |
|||
{"-O"}, |
|||
{"-O2"}, |
|||
{"-Osmall"}, |
|||
{"-W"}, |
|||
{"-Wall"}, |
|||
{"-fobjc-arc"}, |
|||
{"-fno-objc-arc"}, |
|||
{"-fomit-frame-pointer"}, |
|||
{"-fno-omit-frame-pointer"}, |
|||
{"-fpic"}, |
|||
{"-fno-pic"}, |
|||
{"-fPIC"}, |
|||
{"-fno-PIC"}, |
|||
{"-fpie"}, |
|||
{"-fno-pie"}, |
|||
{"-fPIE"}, |
|||
{"-fno-PIE"}, |
|||
{"-fsplit-stack"}, |
|||
{"-fno-split-stack"}, |
|||
{"-fstack-xxx"}, |
|||
{"-fno-stack-xxx"}, |
|||
{"-fsanitize=hands"}, |
|||
{"-g"}, |
|||
{"-ggdb"}, |
|||
{"-march=souza"}, |
|||
{"-mcpu=123"}, |
|||
{"-mfpu=123"}, |
|||
{"-mtune=happybirthday"}, |
|||
{"-mstack-overflow"}, |
|||
{"-mno-stack-overflow"}, |
|||
{"-mmacosx-version"}, |
|||
{"-mnop-fun-dllimport"}, |
|||
{"-pthread"}, |
|||
{"-std=c99"}, |
|||
{"-xc"}, |
|||
{"-D", "FOO"}, |
|||
{"-D", "foo=bar"}, |
|||
{"-I", "."}, |
|||
{"-I", "/etc/passwd"}, |
|||
{"-I", "世界"}, |
|||
{"-framework", "Chocolate"}, |
|||
{"-x", "c"}, |
|||
{"-v"}, |
|||
} |
|||
|
|||
var badCompilerFlags = [][]string{ |
|||
{"-D@X"}, |
|||
{"-D-X"}, |
|||
{"-F@dir"}, |
|||
{"-F-dir"}, |
|||
{"-I@dir"}, |
|||
{"-I-dir"}, |
|||
{"-O@1"}, |
|||
{"-Wa,-foo"}, |
|||
{"-W@foo"}, |
|||
{"-g@gdb"}, |
|||
{"-g-gdb"}, |
|||
{"-march=@dawn"}, |
|||
{"-march=-dawn"}, |
|||
{"-std=@c99"}, |
|||
{"-std=-c99"}, |
|||
{"-x@c"}, |
|||
{"-x-c"}, |
|||
{"-D", "@foo"}, |
|||
{"-D", "-foo"}, |
|||
{"-I", "@foo"}, |
|||
{"-I", "-foo"}, |
|||
{"-framework", "-Caffeine"}, |
|||
{"-framework", "@Home"}, |
|||
{"-x", "--c"}, |
|||
{"-x", "@obj"}, |
|||
} |
|||
|
|||
func TestCheckCompilerFlags(t *testing.T) { |
|||
for _, f := range goodCompilerFlags { |
|||
if err := checkCompilerFlags("test", f); err != nil { |
|||
t.Errorf("unexpected error for %q: %v", f, err) |
|||
} |
|||
} |
|||
for _, f := range badCompilerFlags { |
|||
if err := checkCompilerFlags("test", f); err == nil { |
|||
t.Errorf("missing error for %q", f) |
|||
} |
|||
} |
|||
} |
|||
|
|||
var goodLinkerFlags = [][]string{ |
|||
{"-Fbar"}, |
|||
{"-lbar"}, |
|||
{"-Lbar"}, |
|||
{"-fpic"}, |
|||
{"-fno-pic"}, |
|||
{"-fPIC"}, |
|||
{"-fno-PIC"}, |
|||
{"-fpie"}, |
|||
{"-fno-pie"}, |
|||
{"-fPIE"}, |
|||
{"-fno-PIE"}, |
|||
{"-fsanitize=hands"}, |
|||
{"-g"}, |
|||
{"-ggdb"}, |
|||
{"-march=souza"}, |
|||
{"-mcpu=123"}, |
|||
{"-mfpu=123"}, |
|||
{"-mtune=happybirthday"}, |
|||
{"-pic"}, |
|||
{"-pthread"}, |
|||
{"-Wl,-rpath,foo"}, |
|||
{"-Wl,-rpath,$ORIGIN/foo"}, |
|||
{"-Wl,-R", "/foo"}, |
|||
{"-Wl,-R", "foo"}, |
|||
{"-Wl,-R,foo"}, |
|||
{"-Wl,--just-symbols=foo"}, |
|||
{"-Wl,--just-symbols,foo"}, |
|||
{"-Wl,--warn-error"}, |
|||
{"-Wl,--no-warn-error"}, |
|||
{"foo.so"}, |
|||
{"_世界.dll"}, |
|||
{"./x.o"}, |
|||
{"libcgosotest.dylib"}, |
|||
{"-F", "framework"}, |
|||
{"-l", "."}, |
|||
{"-l", "/etc/passwd"}, |
|||
{"-l", "世界"}, |
|||
{"-L", "framework"}, |
|||
{"-framework", "Chocolate"}, |
|||
{"-v"}, |
|||
{"-Wl,-framework", "-Wl,Chocolate"}, |
|||
{"-Wl,-framework,Chocolate"}, |
|||
{"-Wl,-unresolved-symbols=ignore-all"}, |
|||
} |
|||
|
|||
var badLinkerFlags = [][]string{ |
|||
{"-DFOO"}, |
|||
{"-Dfoo=bar"}, |
|||
{"-W"}, |
|||
{"-Wall"}, |
|||
{"-fobjc-arc"}, |
|||
{"-fno-objc-arc"}, |
|||
{"-fomit-frame-pointer"}, |
|||
{"-fno-omit-frame-pointer"}, |
|||
{"-fsplit-stack"}, |
|||
{"-fno-split-stack"}, |
|||
{"-fstack-xxx"}, |
|||
{"-fno-stack-xxx"}, |
|||
{"-mstack-overflow"}, |
|||
{"-mno-stack-overflow"}, |
|||
{"-mnop-fun-dllimport"}, |
|||
{"-std=c99"}, |
|||
{"-xc"}, |
|||
{"-D", "FOO"}, |
|||
{"-D", "foo=bar"}, |
|||
{"-I", "FOO"}, |
|||
{"-L", "@foo"}, |
|||
{"-L", "-foo"}, |
|||
{"-x", "c"}, |
|||
{"-D@X"}, |
|||
{"-D-X"}, |
|||
{"-I@dir"}, |
|||
{"-I-dir"}, |
|||
{"-O@1"}, |
|||
{"-Wa,-foo"}, |
|||
{"-W@foo"}, |
|||
{"-g@gdb"}, |
|||
{"-g-gdb"}, |
|||
{"-march=@dawn"}, |
|||
{"-march=-dawn"}, |
|||
{"-std=@c99"}, |
|||
{"-std=-c99"}, |
|||
{"-x@c"}, |
|||
{"-x-c"}, |
|||
{"-D", "@foo"}, |
|||
{"-D", "-foo"}, |
|||
{"-I", "@foo"}, |
|||
{"-I", "-foo"}, |
|||
{"-l", "@foo"}, |
|||
{"-l", "-foo"}, |
|||
{"-framework", "-Caffeine"}, |
|||
{"-framework", "@Home"}, |
|||
{"-Wl,-framework,-Caffeine"}, |
|||
{"-Wl,-framework", "-Wl,@Home"}, |
|||
{"-Wl,-framework", "@Home"}, |
|||
{"-Wl,-framework,Chocolate,@Home"}, |
|||
{"-x", "--c"}, |
|||
{"-x", "@obj"}, |
|||
{"-Wl,-rpath,@foo"}, |
|||
{"-Wl,-R,foo,bar"}, |
|||
{"-Wl,-R,@foo"}, |
|||
{"-Wl,--just-symbols,@foo"}, |
|||
{"../x.o"}, |
|||
} |
|||
|
|||
func TestCheckLinkerFlags(t *testing.T) { |
|||
for _, f := range goodLinkerFlags { |
|||
if err := checkLinkerFlags("test", f); err != nil { |
|||
t.Errorf("unexpected error for %q: %v", f, err) |
|||
} |
|||
} |
|||
for _, f := range badLinkerFlags { |
|||
if err := checkLinkerFlags("test", f); err == nil { |
|||
t.Errorf("missing error for %q", f) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func TestCheckFlagAllowDisallow(t *testing.T) { |
|||
if err := checkCompilerFlags("TEST", []string{"-disallow"}); err == nil { |
|||
t.Fatalf("missing error for -disallow") |
|||
} |
|||
os.Setenv("CGO_TEST_ALLOW", "-disallo") |
|||
if err := checkCompilerFlags("TEST", []string{"-disallow"}); err == nil { |
|||
t.Fatalf("missing error for -disallow with CGO_TEST_ALLOW=-disallo") |
|||
} |
|||
os.Setenv("CGO_TEST_ALLOW", "-disallow") |
|||
if err := checkCompilerFlags("TEST", []string{"-disallow"}); err != nil { |
|||
t.Fatalf("unexpected error for -disallow with CGO_TEST_ALLOW=-disallow: %v", err) |
|||
} |
|||
os.Unsetenv("CGO_TEST_ALLOW") |
|||
|
|||
if err := checkCompilerFlags("TEST", []string{"-Wall"}); err != nil { |
|||
t.Fatalf("unexpected error for -Wall: %v", err) |
|||
} |
|||
os.Setenv("CGO_TEST_DISALLOW", "-Wall") |
|||
if err := checkCompilerFlags("TEST", []string{"-Wall"}); err == nil { |
|||
t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall") |
|||
} |
|||
os.Setenv("CGO_TEST_ALLOW", "-Wall") // disallow wins
|
|||
if err := checkCompilerFlags("TEST", []string{"-Wall"}); err == nil { |
|||
t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall and CGO_TEST_ALLOW=-Wall") |
|||
} |
|||
|
|||
os.Setenv("CGO_TEST_ALLOW", "-fplugin.*") |
|||
os.Setenv("CGO_TEST_DISALLOW", "-fplugin=lint.so") |
|||
if err := checkCompilerFlags("TEST", []string{"-fplugin=faster.so"}); err != nil { |
|||
t.Fatalf("unexpected error for -fplugin=faster.so: %v", err) |
|||
} |
|||
if err := checkCompilerFlags("TEST", []string{"-fplugin=lint.so"}); err == nil { |
|||
t.Fatalf("missing error for -fplugin=lint.so: %v", err) |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
package main |
|||
|
|||
/* |
|||
// this name doesn't exist
|
|||
#cgo NOFLAGS: -foo |
|||
|
|||
// unknown flag
|
|||
#cgo CFLAGS: -fdoes-not-exist -DNOTDEFINED |
|||
|
|||
#cgo CFLAGS: -DFOO |
|||
|
|||
#if defined(FOO) |
|||
#define BAR 3 |
|||
#else |
|||
#define BAR 5 |
|||
#endif |
|||
|
|||
#if defined(NOTDEFINED) |
|||
#warning flag must not be defined |
|||
#endif |
|||
*/ |
|||
import "C" |
|||
|
|||
var ( |
|||
_ = C.BAR |
|||
) |
@ -0,0 +1,32 @@ |
|||
// CGo errors:
|
|||
// testdata/flags.go:5:7: invalid #cgo line: NOFLAGS
|
|||
// testdata/flags.go:8:13: invalid flag: -fdoes-not-exist
|
|||
|
|||
package main |
|||
|
|||
import "unsafe" |
|||
|
|||
var _ unsafe.Pointer |
|||
|
|||
const C.BAR = 3 |
|||
|
|||
type C.int16_t = int16 |
|||
type C.int32_t = int32 |
|||
type C.int64_t = int64 |
|||
type C.int8_t = int8 |
|||
type C.uint16_t = uint16 |
|||
type C.uint32_t = uint32 |
|||
type C.uint64_t = uint64 |
|||
type C.uint8_t = uint8 |
|||
type C.uintptr_t = uintptr |
|||
type C.char uint8 |
|||
type C.int int32 |
|||
type C.long int32 |
|||
type C.longlong int64 |
|||
type C.schar int8 |
|||
type C.short int16 |
|||
type C.uchar uint8 |
|||
type C.uint uint32 |
|||
type C.ulong uint32 |
|||
type C.ulonglong uint64 |
|||
type C.ushort uint16 |
Loading…
Reference in new issue