1// Copyright 2018 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package work 6 7import ( 8 "os" 9 "strings" 10 "testing" 11) 12 13var goodCompilerFlags = [][]string{ 14 {"-DFOO"}, 15 {"-Dfoo=bar"}, 16 {"-Ufoo"}, 17 {"-Ufoo1"}, 18 {"-F/Qt"}, 19 {"-F", "/Qt"}, 20 {"-I/"}, 21 {"-I/etc/passwd"}, 22 {"-I."}, 23 {"-O"}, 24 {"-O2"}, 25 {"-Osmall"}, 26 {"-W"}, 27 {"-Wall"}, 28 {"-Wp,-Dfoo=bar"}, 29 {"-Wp,-Ufoo"}, 30 {"-Wp,-Dfoo1"}, 31 {"-Wp,-Ufoo1"}, 32 {"-flto"}, 33 {"-fobjc-arc"}, 34 {"-fno-objc-arc"}, 35 {"-fomit-frame-pointer"}, 36 {"-fno-omit-frame-pointer"}, 37 {"-fpic"}, 38 {"-fno-pic"}, 39 {"-fPIC"}, 40 {"-fno-PIC"}, 41 {"-fpie"}, 42 {"-fno-pie"}, 43 {"-fPIE"}, 44 {"-fno-PIE"}, 45 {"-fsplit-stack"}, 46 {"-fno-split-stack"}, 47 {"-fstack-xxx"}, 48 {"-fno-stack-xxx"}, 49 {"-fsanitize=hands"}, 50 {"-g"}, 51 {"-ggdb"}, 52 {"-march=souza"}, 53 {"-mcmodel=medium"}, 54 {"-mcpu=123"}, 55 {"-mfpu=123"}, 56 {"-mlarge-data-threshold=16"}, 57 {"-mtune=happybirthday"}, 58 {"-mstack-overflow"}, 59 {"-mno-stack-overflow"}, 60 {"-mmacosx-version"}, 61 {"-mnop-fun-dllimport"}, 62 {"-pthread"}, 63 {"-std=c99"}, 64 {"-xc"}, 65 {"-D", "FOO"}, 66 {"-D", "foo=bar"}, 67 {"-I", "."}, 68 {"-I", "/etc/passwd"}, 69 {"-I", "世界"}, 70 {"-I", "=/usr/include/libxml2"}, 71 {"-I", "dir"}, 72 {"-I", "$SYSROOT/dir"}, 73 {"-isystem", "/usr/include/mozjs-68"}, 74 {"-include", "/usr/include/mozjs-68/RequiredDefines.h"}, 75 {"-framework", "Chocolate"}, 76 {"-x", "c"}, 77 {"-v"}, 78} 79 80var badCompilerFlags = [][]string{ 81 {"-D@X"}, 82 {"-D-X"}, 83 {"-Ufoo=bar"}, 84 {"-F@dir"}, 85 {"-F-dir"}, 86 {"-I@dir"}, 87 {"-I-dir"}, 88 {"-O@1"}, 89 {"-Wa,-foo"}, 90 {"-W@foo"}, 91 {"-Wp,-DX,-D@X"}, 92 {"-Wp,-UX,-U@X"}, 93 {"-g@gdb"}, 94 {"-g-gdb"}, 95 {"-march=@dawn"}, 96 {"-march=-dawn"}, 97 {"-mcmodel=@model"}, 98 {"-mlarge-data-threshold=@12"}, 99 {"-std=@c99"}, 100 {"-std=-c99"}, 101 {"-x@c"}, 102 {"-x-c"}, 103 {"-D", "@foo"}, 104 {"-D", "-foo"}, 105 {"-I", "@foo"}, 106 {"-I", "-foo"}, 107 {"-I", "=@obj"}, 108 {"-include", "@foo"}, 109 {"-framework", "-Caffeine"}, 110 {"-framework", "@Home"}, 111 {"-x", "--c"}, 112 {"-x", "@obj"}, 113} 114 115func TestCheckCompilerFlags(t *testing.T) { 116 for _, f := range goodCompilerFlags { 117 if err := checkCompilerFlags("test", "test", f); err != nil { 118 t.Errorf("unexpected error for %q: %v", f, err) 119 } 120 } 121 for _, f := range badCompilerFlags { 122 if err := checkCompilerFlags("test", "test", f); err == nil { 123 t.Errorf("missing error for %q", f) 124 } 125 } 126} 127 128var goodLinkerFlags = [][]string{ 129 {"-Fbar"}, 130 {"-lbar"}, 131 {"-Lbar"}, 132 {"-fpic"}, 133 {"-fno-pic"}, 134 {"-fPIC"}, 135 {"-fno-PIC"}, 136 {"-fpie"}, 137 {"-fno-pie"}, 138 {"-fPIE"}, 139 {"-fno-PIE"}, 140 {"-fsanitize=hands"}, 141 {"-g"}, 142 {"-ggdb"}, 143 {"-march=souza"}, 144 {"-mcpu=123"}, 145 {"-mfpu=123"}, 146 {"-mtune=happybirthday"}, 147 {"-pic"}, 148 {"-pthread"}, 149 {"-Wl,--hash-style=both"}, 150 {"-Wl,-rpath,foo"}, 151 {"-Wl,-rpath,$ORIGIN/foo"}, 152 {"-Wl,-R", "/foo"}, 153 {"-Wl,-R", "foo"}, 154 {"-Wl,-R,foo"}, 155 {"-Wl,--just-symbols=foo"}, 156 {"-Wl,--just-symbols,foo"}, 157 {"-Wl,--warn-error"}, 158 {"-Wl,--no-warn-error"}, 159 {"foo.so"}, 160 {"_世界.dll"}, 161 {"./x.o"}, 162 {"libcgosotest.dylib"}, 163 {"-F", "framework"}, 164 {"-l", "."}, 165 {"-l", "/etc/passwd"}, 166 {"-l", "世界"}, 167 {"-L", "framework"}, 168 {"-framework", "Chocolate"}, 169 {"-v"}, 170 {"-Wl,-sectcreate,__TEXT,__info_plist,${SRCDIR}/Info.plist"}, 171 {"-Wl,-framework", "-Wl,Chocolate"}, 172 {"-Wl,-framework,Chocolate"}, 173 {"-Wl,-unresolved-symbols=ignore-all"}, 174 {"-Wl,-z,relro"}, 175 {"-Wl,-z,relro,-z,now"}, 176 {"-Wl,-z,now"}, 177 {"-Wl,-z,noexecstack"}, 178 {"libcgotbdtest.tbd"}, 179 {"./libcgotbdtest.tbd"}, 180} 181 182var badLinkerFlags = [][]string{ 183 {"-DFOO"}, 184 {"-Dfoo=bar"}, 185 {"-W"}, 186 {"-Wall"}, 187 {"-fobjc-arc"}, 188 {"-fno-objc-arc"}, 189 {"-fomit-frame-pointer"}, 190 {"-fno-omit-frame-pointer"}, 191 {"-fsplit-stack"}, 192 {"-fno-split-stack"}, 193 {"-fstack-xxx"}, 194 {"-fno-stack-xxx"}, 195 {"-mstack-overflow"}, 196 {"-mno-stack-overflow"}, 197 {"-mnop-fun-dllimport"}, 198 {"-std=c99"}, 199 {"-xc"}, 200 {"-D", "FOO"}, 201 {"-D", "foo=bar"}, 202 {"-I", "FOO"}, 203 {"-L", "@foo"}, 204 {"-L", "-foo"}, 205 {"-x", "c"}, 206 {"-D@X"}, 207 {"-D-X"}, 208 {"-I@dir"}, 209 {"-I-dir"}, 210 {"-O@1"}, 211 {"-Wa,-foo"}, 212 {"-W@foo"}, 213 {"-g@gdb"}, 214 {"-g-gdb"}, 215 {"-march=@dawn"}, 216 {"-march=-dawn"}, 217 {"-std=@c99"}, 218 {"-std=-c99"}, 219 {"-x@c"}, 220 {"-x-c"}, 221 {"-D", "@foo"}, 222 {"-D", "-foo"}, 223 {"-I", "@foo"}, 224 {"-I", "-foo"}, 225 {"-l", "@foo"}, 226 {"-l", "-foo"}, 227 {"-framework", "-Caffeine"}, 228 {"-framework", "@Home"}, 229 {"-Wl,-framework,-Caffeine"}, 230 {"-Wl,-framework", "-Wl,@Home"}, 231 {"-Wl,-framework", "@Home"}, 232 {"-Wl,-framework,Chocolate,@Home"}, 233 {"-Wl,--hash-style=foo"}, 234 {"-x", "--c"}, 235 {"-x", "@obj"}, 236 {"-Wl,-rpath,@foo"}, 237 {"-Wl,-R,foo,bar"}, 238 {"-Wl,-R,@foo"}, 239 {"-Wl,--just-symbols,@foo"}, 240 {"../x.o"}, 241 {"-Wl,-R,"}, 242 {"-Wl,-O"}, 243 {"-Wl,-e="}, 244 {"-Wl,-e,"}, 245 {"-Wl,-R,-flag"}, 246} 247 248func TestCheckLinkerFlags(t *testing.T) { 249 for _, f := range goodLinkerFlags { 250 if err := checkLinkerFlags("test", "test", f); err != nil { 251 t.Errorf("unexpected error for %q: %v", f, err) 252 } 253 } 254 for _, f := range badLinkerFlags { 255 if err := checkLinkerFlags("test", "test", f); err == nil { 256 t.Errorf("missing error for %q", f) 257 } 258 } 259} 260 261func TestCheckFlagAllowDisallow(t *testing.T) { 262 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil { 263 t.Fatalf("missing error for -disallow") 264 } 265 os.Setenv("CGO_TEST_ALLOW", "-disallo") 266 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil { 267 t.Fatalf("missing error for -disallow with CGO_TEST_ALLOW=-disallo") 268 } 269 os.Setenv("CGO_TEST_ALLOW", "-disallow") 270 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err != nil { 271 t.Fatalf("unexpected error for -disallow with CGO_TEST_ALLOW=-disallow: %v", err) 272 } 273 os.Unsetenv("CGO_TEST_ALLOW") 274 275 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err != nil { 276 t.Fatalf("unexpected error for -Wall: %v", err) 277 } 278 os.Setenv("CGO_TEST_DISALLOW", "-Wall") 279 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil { 280 t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall") 281 } 282 os.Setenv("CGO_TEST_ALLOW", "-Wall") // disallow wins 283 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil { 284 t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall and CGO_TEST_ALLOW=-Wall") 285 } 286 287 os.Setenv("CGO_TEST_ALLOW", "-fplugin.*") 288 os.Setenv("CGO_TEST_DISALLOW", "-fplugin=lint.so") 289 if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=faster.so"}); err != nil { 290 t.Fatalf("unexpected error for -fplugin=faster.so: %v", err) 291 } 292 if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=lint.so"}); err == nil { 293 t.Fatalf("missing error for -fplugin=lint.so: %v", err) 294 } 295} 296 297func TestCheckCompilerFlagsForInternalLink(t *testing.T) { 298 // Any "bad" compiler flag should trigger external linking. 299 for _, f := range badCompilerFlags { 300 if err := checkCompilerFlagsForInternalLink("test", "test", f); err == nil { 301 t.Errorf("missing error for %q", f) 302 } 303 } 304 305 // All "good" compiler flags should not trigger external linking, 306 // except for anything that begins with "-flto". 307 for _, f := range goodCompilerFlags { 308 foundLTO := false 309 for _, s := range f { 310 if strings.Contains(s, "-flto") { 311 foundLTO = true 312 } 313 } 314 if err := checkCompilerFlagsForInternalLink("test", "test", f); err != nil { 315 // expect error for -flto 316 if !foundLTO { 317 t.Errorf("unexpected error for %q: %v", f, err) 318 } 319 } else { 320 // expect no error for everything else 321 if foundLTO { 322 t.Errorf("missing error for %q: %v", f, err) 323 } 324 } 325 } 326} 327